如何最好地应用WPF MVVM?
我正在尝试设置一个MVVM风格的应用程序,我想我已经通过这些项目的交互并希望有人可以提供帮助。 我在这里做错了吗?
我想我的主要两个问题是
- 我应该如何从我的模型转向我的观点。 目前我正试图通过转换器来做到这一点。
- 如果使用转换器是正确的,我该如何正常工作? 我相信Node构造函数上设置的datacontext被包含转换器的XAML取代。
我的课程(简化了一下):
IFieldDescription
// Interface that is supposed to be the Model public interface IFieldDescription { String Name { get; } bool Disabled { get; } }
节点模型
// Class that is supposed to be the ViewModel public class NodeModel : NotifyPropertyChanged { internal NodeModel() { } public NodeModel(IFieldDescription fieldDescription) { this.FieldDescription = fieldDescription; } protected IFieldDescription FieldDescription { get { return this.fieldDescription; } set { this.fieldDescription = value; this.OnPropertyChanged("Name"); this.OnPropertyChanged("Disabled"); this.OnPropertyChanged("PrimaryKey"); } } private IFieldDescription fieldDescription; public String Name { get { return this.FieldDescription.Name; } } public Boolean Disabled { get { return this.FieldDescription.Disabled; } } }
节点代码背后
public Node(NodeModel model) { this.DataContext = model; this.InitializeComponent(); }
XAML
主窗口
<!---->
主窗口的数据上下文设置为新的RD(),其定义如下: RD
public class RD { private IEnumerable GetTestData() { yield return new FieldDescription("String", true); yield return new FieldDescription("Integer", false); yield return new FieldDescription("Double", false); yield return new FieldDescription("Date", false); yield return new FieldDescription("Enum", false); } public virtual ObservableCollection FieldDescriptions { get { return new ObservableCollection(GetTestData()); } } }
我的转换器目前定义为:
public class ModelToViewConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value == null) return null; if (value is IFieldDescription) { NodeModel model = new NodeModel((IFieldDescription)value); return new Node(model); } return null; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } }
通常我使用DataTemplates
将View
与Model
或ViewModel
绑在一起
我的View的代码隐藏引用模型或ViewModel的唯一地方在启动时将启动ViewModel设置为启动View的DataContext
。 其他所有东西都与DataTemplates
(或Silverlight的DataTemplateSelectors
) DataTemplateSelectors
。
(实际上有时候我确实需要做一些特别的事情,我会在对于代码隐藏中将对象的DataContext
作为ViewModel或Model进行转换,但这些情况很少见,我认为它们是hacks)
例如,设置启动View / ViewModel:
public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); var app = new ShellView(); var context = new ShellViewModel(); app.DataContext = context; app.Show(); } }
以下是一些DataTemplates的示例:
最后,我将在我的XAML中使用ContentControls
来显示我的视图
要么
有时甚至不需要ContentControls。 例如,如果将ListView
绑定到ObservableCollection
,则ListView
每个项都将是NodeModel
类型的对象,WPF将自动为此获取DataTemplate。
MVVM背后的想法是你的整个应用程序在你的ViewModel中运行,而Views只是一个漂亮的UI,它位于ViewModel之上,使它们更加用户友好。 在完美的世界中,View可以轻松地被任何其他UI替换
如果您有兴趣,我的博客上有一个简单的MVVM示例 ,其中包含一些使用MVVM设计模式的示例