Skip to content

Commit 27e0303

Browse files
zhitaopjfversluis
andauthored
Update documentation for ICameraProvider and CameraView (#593)
Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
1 parent 5bb738e commit 27e0303

1 file changed

Lines changed: 88 additions & 3 deletions

File tree

docs/maui/views/camera-view.md

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,48 @@ The `CameraView` can be added to a .NET MAUI application in the following way.
177177

178178
The result will be a surface rendering the output of the default camera connected to the device.
179179

180-
## Access the current camera
180+
## ICameraProvider
181181

182-
The `SelectedCamera` property provides the ability to access the currently selected camera.
182+
The `ICameraProvider` interface provides access to the list of cameras available on the current device, as well as methods for initializing and refreshing that list. It is registered internally as a singleton service when the `CommunityToolkit.Maui.Camera` package is used (see [Getting started](../get-started.md?tabs=CommunityToolkitMauiCamera)), so it can be injected into view models or other classes through the constructor.
183183

184-
The following example shows how to bind the `SelectedCamera` property from the `CameraView` to a property on the `CameraViewModel` with the same name (`SelectedCamera`).
184+
The following example show how to request an `ICameraProvider` through dependency injection and call `InitializeAsync` to obtain a list of available cameras. This performs a one-time discovery of cameras and populates the `AvailableCameras` property. Subsequent calls will reuse the cached results.
185+
186+
```cs
187+
public class CameraViewViewModel(ICameraProvider cameraProvider)
188+
{
189+
readonly ICameraProvider cameraProvider = cameraProvider;
190+
191+
public ObservableCollection<CameraInfo> Cameras { get; } = [];
192+
193+
public async Task InitializeAsync()
194+
{
195+
await cameraProvider.InitializeAsync(CancellationToken.None);
196+
foreach (var camera in cameraProvider.AvailableCameras ?? [])
197+
{
198+
Cameras.Add(camera);
199+
}
200+
}
201+
}
202+
```
203+
204+
If camera availability changes at runtime (e.g. an external USB camera is plugged in), call `RefreshAvailableCameras` to force a refresh. Unlike `InitializeAsync`, this always re-runs camera discovery to ensure the list is up to date, at the cost of performance as it may be expensive on some platforms (e.g., Windows).
205+
206+
```cs
207+
await cameraProvider.RefreshAvailableCameras(CancellationToken.None);
208+
Cameras.Clear();
209+
foreach (var camera in cameraProvider.AvailableCameras ?? [])
210+
{
211+
Cameras.Add(camera);
212+
}
213+
```
214+
215+
## Access and switch the current camera
216+
217+
The `SelectedCamera` property provides the ability to get and set the currently selected camera.
218+
219+
It is a bindable property with default `TwoWay` binding. This means that when it is bound to a property in a view model, updating the `SelectedCamera` of the `CameraView` will also automatically update the corresponding property in the view model.
220+
221+
The following example shows how to bind the `SelectedCamera` property from the `CameraView` to a property on the `CameraViewModel` with the same name (`SelectedCamera`), and a `Picker` to change the selected camera.
185222

186223
```xaml
187224
<ContentPage
@@ -195,11 +232,56 @@ The following example shows how to bind the `SelectedCamera` property from the `
195232
Grid.ColumnSpan="3"
196233
Grid.Row="0"
197234
SelectedCamera="{Binding SelectedCamera}" />
235+
236+
<Picker
237+
Grid.Row="1"
238+
Title="Cameras"
239+
ItemsSource="{Binding Cameras}"
240+
ItemDisplayBinding="{Binding Name}"
241+
SelectedItem="{Binding SelectedCamera}" />
198242
</Grid>
199243

200244
</ContentPage>
201245
```
202246

247+
```cs
248+
public class CameraViewViewModel(ICameraProvider cameraProvider)
249+
{
250+
readonly ICameraProvider cameraProvider = cameraProvider;
251+
252+
public ObservableCollection<CameraInfo> Cameras { get; } = [];
253+
254+
[ObservableProperty]
255+
public partial CameraInfo? SelectedCamera { get; set; }
256+
257+
public async Task InitializeAsync()
258+
{
259+
await cameraProvider.InitializeAsync(CancellationToken.None);
260+
foreach (var camera in cameraProvider.AvailableCameras ?? [])
261+
{
262+
Cameras.Add(camera);
263+
}
264+
// Optionally set an initial camera
265+
SelectedCamera = Cameras.LastOrDefault();
266+
}
267+
}
268+
```
269+
270+
The following describes the different behaviors of the code:
271+
272+
- No initial camera specified
273+
If `SelectedCamera` is not assigned in the view model, the `CameraView` automatically defaults to the first available camera after loading.
274+
Because the binding is `TwoWay`, the `Picker` will also reflect that camera as selected.
275+
276+
- Initial camera specified in the view model
277+
If you assign an initial value (e.g. `SelectedCamera = Cameras.LastOrDefault();`), then both the `CameraView` and the `Picker` will start with that camera selected.
278+
279+
- User changes selection
280+
When the user selects a camera from the `Picker`, the `SelectedCamera` property in the view model is updated, which in turn updates the `CameraView` to display the newly selected camera.
281+
282+
> [!NOTE]
283+
> If the `SelectedCamera` is not specified an initial value, it will be set automatically to the first available camera on the device after the `CameraView` is loaded.
284+
203285
## Control Zoom
204286

205287
The `SelectedCamera` property provides both a `MinimumZoomFactor` and a `MaximumZoomFactor` property, these are read-only and provide developers with a programmatic way of determining what zoom can be applied to the current camera. In order to change the zoom on the current camera the `CameraView` provides the `ZoomFactor` property.
@@ -531,6 +613,9 @@ async void StartCameraRecording(object? sender, EventArgs e)
531613

532614
The `CameraView` provides the ability to programmatically start the preview from the camera. This is possible through both the `StartCameraPreview` method or the `StartCameraPreviewCommand`.
533615

616+
> [!NOTE]
617+
> The camera previw is always automatically started when the `CameraView` is loaded, so you don't need to call `StartCameraPreview` explicitly. The `StartCameraPreview` and `StopCameraPreview` is used to stop and start the camera preview after the `CameraView` is loaded and still active.
618+
534619
The following example shows how to add a `Button` into the application and setup the following bindings:
535620

536621
- Bind the `Command` property of the `Button` to the `StartCameraPreviewCommand` property on the `CameraView`.

0 commit comments

Comments
 (0)