How can I bind source MediaCapture to CaptureElement using Caliburn.Micro?

…衆ロ難τιáo~ 提交于 2019-12-09 06:51:34

问题


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 MediaCapture object to a CaptureElement in the view.


回答1:


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 :)




回答2:


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.




回答3:


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();
}



回答4:


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.



来源:https://stackoverflow.com/questions/23878617/how-can-i-bind-source-mediacapture-to-captureelement-using-caliburn-micro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!