什么是DataContext?

时间:2011-08-31 19:10:23

标签: wpf data-binding

作为问题的继续Linking DataContext with another property in WPF

在研究结束时,我非常惊讶地发现,当一个人写下这样的东西时:

<Label Content="{Binding Path=Name}" />

绑定DataContext属性的Content属于Label控件本身!它仍然有效的事实是由于最近父级的DataContext值的默认继承。

但是,如果您将此标签包装在自定义控件中,并且您不希望将数据绑定到该控件的DataContext属性,那么您可能更愿意拥有:

<Controls:SearchSettings Settings="{Binding Path=Settings}" />

你在这里。现在,您需要将Settings设置为DataContext控件的SearchSettings,以便Label内部绑定,但您不能,因为这将触发重新绑定Settings财产。

我无法看到使用不同来源混合绑定属性的重点:DataContextElementName等。 那么我为什么要使用DataContext

4 个答案:

答案 0 :(得分:89)

写作时

<Label name="myLabel" Content="{Binding Path=Name}" />

您绑定到myLabel.DataContext.Name,而不是myLabel.Name

WPF中的XAML只是一个漂亮的用户界面,可以显示实际数据并与之交互,也称为DataContext。其他绑定源(RelativeSourceElementName等)的目的是指向当前控件DataContext中不存在的另一个属性

<小时/> 所以假设你有一个窗口。如果不设置DataContext,窗口仍会显示,但后面没有数据。

现在假设设置myWindow.DataContext = new ClassA();。现在窗口显示的数据是ClassA。如果ClassA有一个名为Name的属性,我可以编写一个标签并将其绑定到Name(例如您的示例),并且ClassA.Name中存储的任何值都会得到显示。

现在,假设ClassA的属性为ClassB,并且这两个类都有一个名为Name的属性。这是一个XAML块,它说明了DataContext的用途,以及一个控件如何引用不属于它自己的DataContext的属性的示例

<Window x:Name="myWindow"> <!-- DataContext is set to ClassA -->
    <StackPanel> <!-- DataContext is set to ClassA -->

        <!-- DataContext is set to ClassA, so will display ClassA.Name -->
        <Label Content="{Binding Name}" />

         <!-- DataContext is still ClassA, however we are setting it to ClassA.ClassB -->
        <StackPanel DataContext="{Binding ClassB}">

            <!-- DataContext is set to ClassB, so will display ClassB.Name -->
            <Label Content="{Binding Name}" />

            <!-- DataContext is still ClassB, but we are binding to the Window's DataContext.Name which is ClassA.Name -->
            <Label Content="{Binding ElementName=myWindow, Path=DataContext.Name}" /> 
        </StackPanel>
    </StackPanel>
</Window>

如您所见,DataContext基于UI对象背后的任何数据。

更新:我经常从新的WPF用户那里看到这个问题,我将此答案扩展到我博客上的帖子中:What is this “DataContext” you speak of?

答案 1 :(得分:3)

kishore Gaddam来自CodeProject

  

DataContext是数据绑定中最基本的概念之一。 Binding对象需要从某个地方获取其数据,并且有几种方法可以指定数据源,例如直接在Binding中使用Source属性,在树中遍历时从最近的元素继承DataContext ,在Binding对象中设置ElementNameRelativeSource属性。

CodeProject上的详细示例:http://www.codeproject.com/Articles/321899/DataContext-in-WPF

答案 2 :(得分:1)

在这种特殊情况下,你可以这样做:

<Controls:SearchSettings DataContext="{Binding Path=Settings}" Settings="{Binding}" />

假设您希望SearchSettings可能包含的所有内容都使用“设置”作为其数据上下文。基本上,DataContext会影响元素本身以及任何未明确覆盖它的后代。

答案 3 :(得分:1)

在大多数情况下,你想要绑定到DataContext,在ItemsControls的某些模板中,它是绑定到当前模板化项目的唯一方法。对DataContext的进一步绑定很容易编写和阅读,因为它们很简洁。

在您的示例中,您仍然可以设置DataContext,您只需要分别修改设置上的绑定:

<Controls:SearchSettings DataContext="{Binding Settings}" Settings="{Binding}"/>