MVVM中绑定的首选方法,Resources文件中的数据模板或View中的DataContext本身?
这个让我感到难过,因为我想到我看了一切但我必须遗漏一些东西。 我从MSDN杂志中删除了传统的MVVM模式:
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
在学习MVVM的同时。 但是我通常会复制大部分代码,然后根据需要更换它,但今天我想从头开始构建一些东西,看到它可能比我想象的要多。 当我使用资源字典但直接使用datacontext时,MVVM似乎无法使用绑定。 这个问题最终想找到其他开发人员建议使用他们发现的绑定。
问题的摘要是这样的:为什么资源字典中的’DataTemplate’看起来不起作用,但直接’DataContext’方法立即用于绑定视图?
是因为我在后面的代码中使用设置视图混合了代码。 或者可能是因为别的东西。 如果我直接在View的XAML中设置’DataContext’,那么看起来我的属性和它的实现在viewmodel中设置正确,但为什么不在资源字典中呢? 我认为这种方法的优点是你可以同时设置一堆关系。 我很好奇是否需要进行其他设置才能使其正常工作。 在MVVM方法的主要示例中,他们使用数据模板很奇怪但似乎还有更多的设置它们,而不是我正在做的让它们的“绑定”工作。
什么不适合我:
我试图在主窗口xaml中做一些非常基本的东西,留下我的一些代码,使它更简单:
主窗口XAML:
主窗口代码背后:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.WindowState = WindowState.Maximized; } private void mnuDataBoundSeriesMVVMCharting_OnClick(object sender, RoutedEventArgs e) { View.DataBoundMVVMChart c = new DataBoundMVVMChart(); dockchildren.Children.Clear(); dockchildren.Children.Add(c); } } }
资源词典:
DataBoundMVVMChart.xaml的视图:
ViewModel绑定到上面的View:
namespace WPFTesting12_2.ViewModel { class DataBoundMVVMChartViewModel : INotifyPropertyChanged { private string _HelloString; public string HelloString { get { return _HelloString; } set { _HelloString = value; RaisePropertyChanged("HelloString"); } } public DataBoundMVVMChartViewModel() { HelloString = "Hello there from the ViewModel"; } public event PropertyChangedEventHandler PropertyChanged; protected void RaisePropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } }
好了,现在绑定将在视图中失败但是颜色的资源会进来。所以我认为我做错了什么但是后面的代码会马上获得属性。 让我们继续:
什么工作:
神奇地,如果我只是将这四行添加到视图中:
将其添加到顶部“UserControl”段中的声明:
xmlns:local="clr-namespace:WPFTesting12_2.ViewModel"
然后设置对UserControl的DataContext的引用:
在使用WPF时,重要的是要有两层:数据层( DataContext
)和UI层(XAML)。
绑定用于将数据从数据层提取到View层。
当你写作
您告诉WPF它应该创建一个DataBoundMVVMChartViewModel
的新实例,并将其用于该UserControl的数据层。
当你写作
您告诉Label在其数据层( DataContext
)中查找名为“HelloString”的属性,并将其用于Content
属性。
如果数据层中不存在属性“HelloString”(除非您像使用
那样设置DataContext
否则它不会存在),绑定将失败并且除输出中的绑定错误外不会显示任何内容窗口。
ResourceDictionary
DataTemplate
与DataContext
不同。
实际上, ResourceDictionary
就像听起来一样 – WPF可以在需要时在应用程序中使用的资源字典。 但是,Dictionary中的对象默认情况下不是应用程序UI本身的一部分。 相反,它们需要以某种方式被引用才能使用。
但是回到你的DataTemplate
WPF使用DataTemplates了解如何绘制特定类型的对象。 在您的情况下,此DataTemplate
告诉WPF,只要它需要绘制DataBoundMVVMChartViewModel
类型的对象,它应该通过使用DataBoundMVVMChart
。
要将对象插入UI,通常使用Content
属性,例如
MyLabel.Content = new DataBoundMVVMChartViewModel();
要么
我实际上开始用你在问题中链接的完全相同的文章学习MVVM,并且很难搞清楚它,这让我做了一些关于WPF / MVVM的博客,专门针对像我这样的初学者:)
如果你有兴趣,我有一些关于WPF / MVVM的博客文章可以帮助你更好地理解这项技术。
-
你说的这个“DataContext”是什么?
-
一个简单的MVVM示例
至于你的实际问题:
MVVM中绑定的首选方法,Resources文件中的数据模板或View中的DataContext本身?
我更喜欢在.Resources
某个地方使用DataTemplate
,因为那时你的UI并没有特定地绑定一个特定的DataContext
。
在使用MVVM创建可重用控件时,这一点尤为重要。 例如,如果您有一个CalculatorUserControl
,并且您在控件本身中为其分配了一个DataContext
,例如使用
,则您永远不能将该CalculatorUserControl
与除控件之外创建的DataContext
之外的任何其他DataContext
一起使用。创建。
所以我通常在启动时为整个应用程序设置一次DataContext
,并使用DataTemplates
告诉WPF如何在我的应用程序中绘制不同的ViewModels
或Models
。
我的整个应用程序都存在于数据层中,而XAML只是一个与数据层交互的用户友好界面。 (如果你想看一个代码示例,请查看我的Simple MVVM示例post)
如果要使用隐式DataTemplates
,则必须使用view-model-first方法,但是您可以在没有视图模型作为其上下文的情况下向DockPanel
添加视图 。 如果只是添加相应的视图模型(到ContentControl
或ItemsControl
),将从DataTemplate
自动创建视图,并将视图模型作为其DataContext
。
例如
ic.Items.Add(new DataBoundMVVMChartViewModel());
我个人更喜欢这个优先于视图 (例如添加一个视图然后分配自己的DataContext
),因为你通常想要引用视图模型,视图只是次要的并且通过与视图模型交互来间接操作。