在代码而不是XAML中设置DataContext有什么好处? [英] What is the advantage of setting DataContext in code instead of XAML?

查看:165
本文介绍了在代码而不是XAML中设置DataContext有什么好处?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在WPF中定义DataContext似乎有两种主要方式:

There seem to be two main ways to define DataContext in WPF:



  • either in code like this:

App.xaml.cs(取自 WPF MVVM Toolkit模板):

App.xaml.cs (taken from the WPF MVVM Toolkit template):

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();
    }
}




  • 在XAML 中,如下所示:

    • or in XAML like this:
    • Window1.xaml:

      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>
      

      在XAML中定义DataContext的一个优点是,您的数据显示在Expression Blend中设计模式和Expression Blend允许您在GUI中做很多工作,例如从数据源等中选择字段。如下所示

      One advantage that defining the DataContext in XAML has is that your data shows up in Expression Blend design mode and Expression Blend allows you to do quite a lot within the GUI e.g. choose fields from your datasource, etc. as shown here.

      我已经阅读了绑定 ADO.NET对象不能绑定在XAML (虽然我不明白为什么你可以写一个最小的包装器你可以从XAML绑定的对象)。

      I have read that binding ADO.NET objects cannot be bound in XAML (although I don't see why you could write a minimal wrapper for them to which you could bind from XAML).

      奇怪的是,WPF的WPF团队使WPF MVVM模板在代码中定义了DataContext,因为您的数据不会出现在设计模式中,这通常是布局的重要组成部分,因此很快使编辑您的表达式混合视图变得不切实可行。

      Strange that the WPF Team in making the WPF MVVM templates define the DataContext in code which very quickly makes it impracticable to edit your Views in Expression Blend, since your data doesn't show up in design mode which is often a significant part of the layout.

      所以我在这里认为必须有一些优势在设置DataContext代码而不是XAML的路上,任何人都知道是什么?

      So I'm thinking there must be some advantage down the road to setting the DataContext in code instead of XAML, anyone know what it is?

      推荐答案

      你可以(也许在2009年你不能)通过使用 d:DataContext 的属性获得两个世界的最佳e。你不需要任何 ViewModelLocator craziness 如果您还没有准备好: - )

      You can (maybe in 2009 you couldn't) get the best of both worlds by using the d:DataContext attribute. You don't need any of that ViewModelLocator craziness if you're not ready for that yet :-)

      确保您在根元素中定义了以下XML命名空间:

      First make sure that you have the following XML namespace defined in your root element:

      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      

      然后,您可以将以下属性添加到您的xaml:

      Then you can add the following attribute to an element in your xaml:

      d:DataContext ={d:DesignInstance IsDesignTimeCreatable = True,Type = vm:CustomerInsightViewModel}

      在您的xaml codebehind中:

      In your xaml codebehind :

          public CustomerInsightUserControl()
          {
              InitializeComponent();
      
              if (!DesignerProperties.IsInDesignTool)
              {
                  DataContext = new CustomerInsightViewModel();
              }
          }
      

      然后在您的ViewModel中:

      Then in your ViewModel:

          public CustomerInsightViewModel()
          {
              if (IsInDesignMode)
              {
                  // Create design time data
                  Customer = new Customer() {
                      FirstName=... 
                  }
              }
              else {
                  // Create datacontext and load customers
              }
          }
      

      不要错过 IsDesignTimeCreatable = True 或者混合不会实例化你的课程

      Don't miss the IsDesignTimeCreatable=True or else Blend won't instantiate your class

      这篇关于在代码而不是XAML中设置DataContext有什么好处?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆