我正在尝试实现MVVM设计模式。我有一个方法,在我的代码后面的文件绑定到一个按钮点击事件,打开一个教学视频,如下所示:
private void OpenvideoButton_MouseDown(object sender, MouseButtonEventArgs e)
{
try
{
Process.Start(@"Instructional_Video.wmv");
}catch
{
MessageBox.Show("Error playing instructional video");
}
e.Handled = true;
}
我的问题是我应该在MVVM架构中将代码放在哪里? 由于视频是一个图形对象,因为MessageBox我正在考虑将其保留在代码中,但我也非常谨慎地将代码留在那里。
在符合MVVM最佳实践的情况下,我应该在哪里保留上述代码?
答案 0 :(得分:1)
代码,"会谈"外部世界(操作系统,文件系统,数据库,Web服务,UI层等)应放在服务中 - 当您为视图模型编写单元测试时,可以模拟的对象。
使用依赖注入容器(如MEF,AutoFac,NInject等)将服务注入视图模型是一种很好的做法。
这样的事情:
public interface IPlayerLauncher
{
void Launch(string fileName);
}
public interface IDialogService
{
void ShowMessageBox(string message);
}
public class SomeViewModel
{
private readonly IPlayerLaucher playerLauncher;
private readonly IDialogService dialogService;
private void HandleOpenVideo()
{
try
{
playerLauncher.Launch("Instructional_Video.wmv");
}
catch
{
dialogService.ShowMessageBox("Error playing instructional video");
}
}
public SomeViewModel(IPlayerLaucher playerLaucher, IDialogService dialogService)
{
this.playerLauncher = playerLauncher;
this.dialogService = dialogService;
OpenVideoCommand = new RelayCommand(HandleOpenVideo);
}
public ICommand OpenVideoCommand { get; }
}
public class PlayerLaucher : IPlayerLauncher
{
public void Lauch(string fileName)
{
Process.Start(fileName);
}
}
public class DialogService : IDialogService
{
public void ShowMessageBox(string message)
{
MessageBox.Show(message);
}
}
RelayCommand
(也是DelegateCommand
)是ICommand
的实现,它执行传递的委托。互联网上有很多实施样本。
不是处理点击事件,而是将按钮绑定到OpenVideoCommand
。
请注意,像这样的异常处理不是一个好的选择,但这与此问题无关。