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视图AudioCaptureViewModel
- 包含所有音频捕获逻辑的ViewModel 要创建全屏音频捕获对话框,我发现最好的方法是使用Popup
并将其子项设置为AudioCaptureView
。我对这种方法的问题在于它推动我使用View-First模式。由于我使用的是Caliburn Micro,我希望能够通过首先创建ViewModel来使用CM来实例化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端口。
答案 0 :(得分:0)
Caliburn.Micro
WindowManager
可能会取得一些成功。在官方文档中没有太多关于它(你最好搜索谷歌和CM的讨论)。我在我的一个应用程序中使用它,我需要在新窗口中托管特定的ViewModel
,并希望利用所有Caliburn.Micro
善良(以及我现有的Views
)
看一下Caliburn.Micro.IWindowManager
界面,你会看到一些方便的方法,你可以从一个WindowManager实例调用(取决于你之后的弹出窗口类型)。
public interface IWindowManager
{
bool? ShowDialog(object rootModel, object context = null, IDictionary<string, object> settings = null);
void ShowPopup(object rootModel, object context = null, IDictionary<string, object> settings = null);
void ShowWindow(object rootModel, object context = null, IDictionary<string, object> settings = null);
}
在我的应用程序中,要使用我选择的ViewModel
弹出我的窗口,我在这些行中做了一些事情(插入了你的名字):
// Some basic Window settings.
dynamic settings = new ExpandoObject();
settings.Title = "Test Window";
settings.WindowStartupLocation = WindowStartupLocation.Manual;
settings.SizeToContent = SizeToContent.Manual;
settings.Width = 450;
settings.Height = 300;
var localAudioCaptureViewModel new AudioCaptureViewModel ();
WindowManagerFactory.WindowManager.ShowWindow(localAudioCaptureViewModel, null, settings); // I didn't require context (null)
Caliburn.Micro应该将你的视图解析为正确的ViewModel,你很高兴。
答案 1 :(得分:0)
您始终可以在自己的项目中将WindowManager移植到WinRT。看看来源我不认为太多需要改变。 https://caliburnmicro.codeplex.com/SourceControl/latest#src/Caliburn.Micro.Platform/net40/WindowManager.cs
你也可以带接口并使用DI,但为了时间的缘故,这里是独立的课程。模型第一次绑定的主要部分是ViewLocator.LocateForModel
,它从ViewModel返回视图(又称魔术)
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