On Windows Phone 8.1, I am using the Caliburn.Micro view-model-first approach, but as the view model cannot have any knowledge of the view, I cannot see how I can bind a MediaCa
Adding to Hawlett's answer, I had to do a little bit more to get the camera displaying correctly. I have changed ConfigureMedia() to be:
private async void ConfigureMedia()
{
_deviceInformationCollection = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
await MediaCapture.InitializeAsync(new MediaCaptureInitializationSettings
{
VideoDeviceId = _deviceInformationCollection[_deviceInformationCollection.Count - 1].Id
// The rear-facing camera is the last in the list
});
MediaCapture.VideoDeviceController.PrimaryUse = CaptureUse.Photo;
MediaCapture.SetPreviewRotation(VideoRotation.Clockwise90Degrees);
CaptureElement.Source = MediaCapture;
CaptureElement.Stretch = Stretch.UniformToFill;
await MediaCapture.StartPreviewAsync();
}
I had the same problem. I'm using MVVM Light with Windows Phone 8.1 WinRT (Universal Apps).
I used ContentControl and binded to CaptureElement:
<ContentControl HorizontalAlignment="Left"
Width="320" Height="140" Content="{Binding CaptureElement}"/>
CaptureElement and MediaCapture are properties in my ViewModel:
private MediaCapture _mediaCapture;
public MediaCapture MediaCapture
{
get
{
if (_mediaCapture == null) _mediaCapture = new MediaCapture();
return _mediaCapture;
}
set
{
Set(() => MediaCapture, ref _mediaCapture, value);
}
}
private CaptureElement _captureElement;
public CaptureElement CaptureElement
{
get
{
if (_captureElement == null) _captureElement = new CaptureElement();
return _captureElement;
}
set
{
Set(() => CaptureElement, ref _captureElement, value);
}
}
And next I call ConfigureMedia() in ViewModel's constructor:
async void ConfigureMedia()
{
await MediaCapture.InitializeAsync();
CaptureElement.Source = MediaCapture;
await MediaCapture.StartPreviewAsync();
}
It's important to firstly initialize MediaCapture, next set Source and finally StartPeview. For me it works :)
I used ContentControl
and bound to CaptureElement
and It works for me but only the first time. If I navigate to another page and I come back to camera's page I can't see camera preview. I don't call method as StopPreviewAsync()
I only navigate to another page.
If you're trying to keep strict view / view model separation then there are couple of possibilities.
Have you tried straight binding?
<CaptureElement Source="{Binding SomeMediaCapture}" />
If that doesn't work another one is create your own attached property that you could put on CaptureElement. When that property is set you can set the source yourself.
<CaptureElement custom:CaptureHelper.Source="{Binding SomeMediaCapture}" />
Here's a sample of doing some similar with web view and creating an html binding.
The way I tend to do this though is create an interface abstracting the view (say ICaptureView) that the view implements.
I can then cast the view held by the view model
var captureView = (ICaptureView) GetView();
where ICaptureView implements a SetCaptureSource method. This way it's still testable as you can attach a mock ICaptureView to the view model for testing.