Windows.Media.Captures
有一个方便的 CameraCaptureUI
类,可以如下实例化以向用户显示一个对话框以捕获照片或视频:
// Create dialog to Capture Video
CameraCaptureUI dialog = new CameraCaptureUI();
dialog.VideoSettings.Format = CameraCaptureUIVideoFormat.Mp4;
StorageFile file = await dialog.CaptureFileAsync(CameraCaptureUIMode.Video);
if (file != null)
{
// Do something with file...
}
我想创建我自己的自定义音频捕获类,其工作方式非常相似:
// Create dialog to Capture Audio
AudioCaptureUI dialog = new AudioCaptureUI();
StorageFile file = await dialog.CaptureFileAsync();
if (file != null)
{
// Do something with file...
}
为了完成上述工作,我创建了以下三个文件:
AudioCaptureUI
- 用户实例化以显示音频捕获对话框的类AudioCaptureView
- 音频捕捉体验的 UI ViewAudioCaptureViewModel
- 包含所有音频捕获逻辑的 ViewModel
要创建全屏音频捕获对话框,我发现最好的方法是使用 Popup
并将其子项设置为 AudioCaptureView
。这种方法的问题是它促使我使用 View-First 模式。由于我使用的是 Caliburn Micro,因此我希望能够使用 CM 通过首先创建 ViewModel 来实例化 View 。
我目前拥有的是以下几行:
public class AudioCaptureUI
{
private Popup _popup;
private TaskCompletionSource<StorageFile> _taskCompletionSource;
public IAsyncOperation<StorageFile> CaptureFileAsync()
{
// Force my View to be full screen
AudioCaptureView audioCaptureView = new AudioCaptureView
{
Width = Window.Current.Bounds.Width,
Height = Window.Current.Bounds.Height
};
// Creating View, instead of a ViewModel. Renders Caliburn Micro useless!
_popup = new Popup { Child = audioCaptureView };
if (_popup.Child != null)
{
SubscribeEvents();
_popup.IsOpen = true;
}
return AsyncInfo.Run(WaitForInput);
}
...
}
上述模式有效。但是,我不得不手动连接所有操作,无法利用 Caliburn Micro 的 MVVM 优势。
我还应该如何从我的 AudioCaptureUI
类以编程方式实例化 ViewModel?
同样重要的是要强调我正在开发一个 Windows 应用商店应用 并使用 WinRT CM 端口。
最佳答案
您始终可以在自己的项目中将 WindowManager 移植到 WinRT。查看源代码,我认为不需要更改太多。 https://caliburnmicro.codeplex.com/SourceControl/latest#src/Caliburn.Micro.Platform/net40/WindowManager.cs
您也可以引入接口(interface)并使用 DI,但为了时间的缘故,这里是独立类。模型优先绑定(bind)的主要部分是 ViewLocator.LocateForModel
,它从 ViewModel 返回 View (又名魔法)
using System;
using System.Collections.Generic;
using Windows.UI.Xaml.Controls.Primitives;
namespace Caliburn.Micro
{
public class WindowManager
{
public virtual void ShowPopup(object rootModel, object context = null, IDictionary<string, object> settings = null)
{
var popup = CreatePopup(rootModel, settings);
var view = ViewLocator.LocateForModel(rootModel, popup, context);
popup.Child = view;
//popup.SetValue(View.IsGeneratedProperty, true);
ViewModelBinder.Bind(rootModel, popup, null);
Caliburn.Micro.Action.SetTargetWithoutContext(view, rootModel);
var activatable = rootModel as IActivate;
if (activatable != null)
{
activatable.Activate();
}
var deactivator = rootModel as IDeactivate;
if (deactivator != null)
{
popup.Closed += delegate { deactivator.Deactivate(true); };
}
popup.IsOpen = true;
//popup.CaptureMouse();
}
protected virtual Popup CreatePopup(object rootModel, IDictionary<string, object> settings)
{
var popup = new Popup();
ApplySettings(popup, settings);
return popup;
}
bool ApplySettings(object target, IEnumerable<KeyValuePair<string, object>> settings)
{
if (settings != null)
{
var type = target.GetType();
foreach (var pair in settings)
{
var propertyInfo = type.GetPropertyCaseInsensitive(pair.Key);
if (propertyInfo != null)
{
propertyInfo.SetValue(target, pair.Value, null);
}
}
return true;
}
return false;
}
}
}
然后您需要做的就是创建一个实例并给它一个 ViewModel:
var windowManager = new WindowManager();
windowManager.ShowPopup(new MyPopupThingViewModel());
注意:我只在 8.1 应用程序中使用过它,所以不能 100% 确定它是否完全适用于 8.0
关于c# - 以编程方式创建一个带有由 Caliburn Micro 初始化的子元素的弹出窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20730061/