Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 在代码中设置DataContext而不是XAML的优点是什么?_Wpf_Xaml_Data Binding_Expression Blend_Datacontext - Fatal编程技术网

Wpf 在代码中设置DataContext而不是XAML的优点是什么?

Wpf 在代码中设置DataContext而不是XAML的优点是什么?,wpf,xaml,data-binding,expression-blend,datacontext,Wpf,Xaml,Data Binding,Expression Blend,Datacontext,在WPF中定义DataContext似乎有两种主要方法: 代码中的如下所示: App.xaml.cs(摘自): 或在XAML中如下所示: Window1.xaml: <DockPanel> <StackPanel HorizontalAlignment="Left" DockPanel.Dock="Top" Orientation="Horizontal"> <StackPanel.Da

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

  • 代码中的如下所示:
App.xaml.cs(摘自):

  • 或在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中执行大量操作,例如从数据源中选择字段等

我已经读到绑定ADO.NET对象不能在XAML中绑定(尽管我不明白为什么您可以为它们编写一个最小的包装器,您可以从XAML绑定到该包装器)

奇怪的是,制作WPF MVVM模板的WPF团队在代码中定义了DataContext,这很快使在Expression Blend中编辑视图变得不切实际,因为您的数据不会显示在设计模式中,而设计模式通常是布局的重要部分


所以我认为在代码中设置DataContext而不是XAML的过程中肯定有一些优势,有人知道它是什么吗?

在codebehind中设置DataContext可以很容易地使用unity注入DataContext。

我不喜欢让Expression Blend尝试实例化我的数据对象


我通过代码设置DataContext,在这里我可以使用依赖项注入来注入适当的对象、服务、提供者或我用来查找代码的其他内容

可能有一种解决方案,使用DataObjectProvider来掩盖数据在XAML之外实例化的事实

它将说明DataContext的类型,这应该足以让Blend拾取属性


我还没有尝试过这一点,所以请恕我直言,但它确实值得研究。

请参阅Rob关于Blend中设计时数据的文章:

通过使用
d:DataContext
属性,您可以(也许在2009年您无法)充分利用这两个方面的优势。如果您还没有准备好,您不需要任何这些:-)

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

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
然后,可以向xaml中的元素添加以下属性:

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

在xaml代码隐藏中:

    public CustomerInsightUserControl()
    {
        InitializeComponent();

        if (!DesignerProperties.IsInDesignTool)
        {
            DataContext = new CustomerInsightViewModel();
        }
    }
然后在ViewModel中:

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

不要错过
isdesigntimecreateable=True
,否则Blend不会实例化您的类

根据我的经验,最好至少根据它将显示的数据样本设计一个接口布局。否则,就是对廉价的洞察和昂贵的疏忽视而不见。

也可以使用ObjectDataProvider使用Unity或此处暗示的其他IOC建立对象工厂

特别是


是否有一个两全其美的解决方案?这是否意味着,如果您使用复合应用程序库/Unity,您基本上可以从Expression Blend中剪切和粘贴,或者是否有一种简单的方法,例如在XAML中使用模拟默认数据上下文,设计者可以在Blend中使用?请参阅我在DataobjectProvider上的回答。它可以用作一个门面来委托实例化并使用来自DI的内容。如果在开始“属性'DataContext'必须在默认命名空间中…”时出现编译时错误,解决方案如下
    public CustomerInsightViewModel()
    {
        if (IsInDesignMode)
        {
            // Create design time data
            Customer = new Customer() {
                FirstName=... 
            }
        }
        else {
            // Create datacontext and load customers
        }
    }