Edw*_*uay 13 data-binding wpf datacontext xaml expression-blend
在WPF中定义DataContext似乎有两种主要方式:
App.xaml.cs(取自WPF MVVM Toolkit模板):
public partial class App : Application
{
private void OnStartup(object sender, StartupEventArgs e)
{
// Create the ViewModel and expose it using the View's DataContext
MainView mainView = new MainView();
MainViewModel mainViewModel = new MainViewModel();
mainViewModel.LoadCustomers("c:\\testdata2\\Customers.xml");
mainView.DataContext = mainViewModel;
mainView.Show();
}
}
Run Code Online (Sandbox Code Playgroud)
Window1.xaml:
<DockPanel>
<StackPanel
HorizontalAlignment="Left"
DockPanel.Dock="Top"
Orientation="Horizontal">
<StackPanel.DataContext>
<local:CustomerViewModel />
</StackPanel.DataContext>
<TextBlock Text="{Binding Path=FirstName}" />
<TextBlock Text=" " />
<TextBlock Text="{Binding Path=LastName}" />
</StackPanel>
<StackPanel
HorizontalAlignment="Left"
VerticalAlignment="top"
DockPanel.Dock="Top"
Orientation="Horizontal">
<ListBox ItemsSource="{Binding Source={StaticResource FileNames}}" />
</StackPanel>
<StackPanel
HorizontalAlignment="Left"
VerticalAlignment="top"
DockPanel.Dock="Top"
Orientation="Horizontal">
<ComboBox
ItemsSource="{Binding Source={StaticResource Directories}}"
SelectedIndex="0" />
</StackPanel>
<StackPanel
HorizontalAlignment="Left"
VerticalAlignment="top"
DockPanel.Dock="Top"
Orientation="Horizontal">
<StackPanel.DataContext>
<local:SystemInformationViewModel />
</StackPanel.DataContext>
<TextBlock Text="{Binding Path=CurrentTime}" />
</StackPanel>
</DockPanel>
Run Code Online (Sandbox Code Playgroud)
在XAML中定义DataContext的一个优点是,您的数据显示在Expression Blend设计模式中,Expression Blend允许您在GUI中执行相当多操作,例如从数据源中选择字段等,如此处所示.
我已经读过,绑定ADO.NET对象不能绑定在XAML中(虽然我不明白为什么你可以为它们编写一个可以从XAML绑定的最小包装器).
很奇怪WPF团队在制作WPF MVVM模板时会在代码中定义DataContext,这很快就会使在Expression Blend中编辑视图变得不切实际,因为您的数据不会出现在设计模式中,而设计模式通常是布局的重要部分.
所以我认为在代码中设置DataContext而不是XAML 必须有一些优势,任何人都知道它是什么?
Sim*_*ver 15
你可以(可能在2009年你不能)通过使用d:DataContext属性获得两全其美.如果你尚未做好准备,你不需要任何这种ViewModelLocator疯狂 :-)
首先确保在根元素中定义了以下XML命名空间:
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
Run Code Online (Sandbox Code Playgroud)
然后,您可以将以下属性添加到xaml中的元素:
d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True, Type=vm:CustomerInsightViewModel}"
在你的xaml代码隐藏中:
public CustomerInsightUserControl()
{
InitializeComponent();
if (!DesignerProperties.IsInDesignTool)
{
DataContext = new CustomerInsightViewModel();
}
}
Run Code Online (Sandbox Code Playgroud)
然后在你的ViewModel中:
public CustomerInsightViewModel()
{
if (IsInDesignMode)
{
// Create design time data
Customer = new Customer() {
FirstName=...
}
}
else {
// Create datacontext and load customers
}
}
Run Code Online (Sandbox Code Playgroud)
不要错过,IsDesignTimeCreatable=True否则Blend不会实例化你的课程
我不喜欢让Expression Blend尝试实例化我的数据对象.
我通过代码设置DataContext,我可以使用依赖注入来注入适当的对象,服务,提供程序或我用来查找代码的其他内容.