对ViewModel的MVVM视图引用
我正在WPF应用程序中使用MVVM。我对这两个都很陌生。让我声明,我不是MVVM模式中的纯粹主义者,我正在尝试使用尽可能多的最佳实践,但我正在尝试做出我认为合理的妥协,以使其在我们的环境中工作。例如,我不想在我的视图中实现0%的代码代码代码隐藏 我有几个关于最佳实践的问题 1) 我知道我不想让我的虚拟机知道附加的视图,但是视图引用其虚拟机是否合理 2) 如果视图中的控件打开了另一个视图(如对话框),我应该在视图中处理这个问题吗?在虚拟机中处理它似乎是错误的,因为虚拟机对特定视图有一些了解。1)。视图需要在某个级别上引用视图模型,因为视图模型将充当视图的datacontext 2) 处理此问题的一种方法是使用表示对话框的通用viewmodel,该对话框由主viewmodel(用作views datacontext的viewmodel)拥有 您可以使用命令包装对话框viewmodel的新实例,该实例将在资源中定义相应的datatemplate。此模板将被设置为绑定到dialogviewmodel类型。1)以下是视图“了解”ViewModel的两个简单实践。视图了解ViewModel(用于数据绑定)是合理的,但在您的案例中可能不需要它。看看这些方法是否有助于解决您的问题。还有其他方法,但这些方法应该足够简单:对ViewModel的MVVM视图引用,mvvm,Mvvm,我正在WPF应用程序中使用MVVM。我对这两个都很陌生。让我声明,我不是MVVM模式中的纯粹主义者,我正在尝试使用尽可能多的最佳实践,但我正在尝试做出我认为合理的妥协,以使其在我们的环境中工作。例如,我不想在我的视图中实现0%的代码代码代码隐藏 我有几个关于最佳实践的问题 1) 我知道我不想让我的虚拟机知道附加的视图,但是视图引用其虚拟机是否合理 2) 如果视图中的控件打开了另一个视图(如对话框),我应该在视图中处理这个问题吗?在虚拟机中处理它似乎是错误的,因为虚拟机对特定视图有一些了解。1)。
public View(ViewModel vm)
{
View.DataContext = vm;
}
public Bootstrapper(View v, ViewModel vm)
{
v.DataContext = vm;
//or, if you want it to have no parameters
View v = new View();
ViewModel vm = new ViewModel();
v.DataContext = vm;
}
如果您有一个服务定位工具,那么第一个选项也不错,但是有一种MVVM的味道,它不喜欢视图的代码隐藏中的任何代码。第二个选项也不错,对于您的任务来说应该足够简单
2.)这个问题可能是MVVM设计中的一个难点。如果我们谈论的是一个普通的Win32 MessageBox,我通常会将该逻辑分离成一个附加对象,并将其放入VM中。这种方式更为清晰。(例如,我在列表框中选择了一个项目,我在该操作中附加了一个删除ICommand,在我的ViewModel中,当执行此ICommand时,我会戳我的MessageBoxObject以询问用户是否“真的想删除”此项目)。更高级的“对话框”将为这些视图模型使用额外的视图模型和数据模板。我更喜欢这种方法。1)视图通过DataContext明确引用了ViewModel。并且您可以在视图中强制转换DataContext:
public class ShellView : Window
{
…
public ShellViewModel { get { return DataContext as ShellViewModel; } }
这与模型-视图-模型模式没有冲突
2) 你说得对。ViewModel不应打开其他视图。更好的方法是使用控制器。他们负责应用程序的工作流
如果您对更详细的信息感兴趣,那么您可以查看
我发现Rob Eisenberg建议的方法非常有趣
要点:
我强烈建议你看这段视频。很晚了,但我认为这很棘手,应该有很多不同的视角
我知道我不想让我的虚拟机知道附加的视图,但是 视图引用其VM是否合理 如前所述,正确的视图ViewModel排列需要将ViewModel指定为视图的DataContext属性。这允许从声明性XAML“自动”建立数据绑定,或者通过代码隐藏进行微调 有时,您可能会在代码隐藏中编写以下内容:
var dc = DataContext as CleverViewModel;
CleverViewModel.CleverProperty.Add(someValue); // just a simple example
我认为实现这类事情的正确方法不是投射数据上下文,而是:
var collection=(observetecollection)cleverControl.ItemsSource;
收藏。添加(someValue)代码>
ObservableCollection
的名为CleverProperty
的属性。这使我能够拥有多态甚至鸭子类型的视图模型
如果视图中的控件打开另一个视图(如对话框),我应该 在视图中处理此问题?在VM中处理它似乎是错误的,因为 然后VM对特定视图有一些了解 这不应该发生在严格的MVVM中,并且不难避免使用数据模板。DataTemplates将给定类型的DataContext映射到给定类型的视图,因此只要ContentControl的DataContext更改,其显示也会更改,前提是您具有该类型的DataTemplate:
还有更多微妙之处,但我一直在使用这种方法,并取得了良好的效果。希望这对某人有所帮助。+1但我认为对于第1点),OP询问View类是否可以了解确切的ViewModel类,而不仅仅是通过属性名绑定未知类型的datacontext。根据Wim,实际上我指的是View类引用ViewModel,而不仅仅是通过数据绑定(这是抽象的)。关于第2点,我使用MVVM Light toolkit创建视图,然后通过定位器服务绑定到ViewModel。所以我不是cre