什么是DataContext? [英] What is DataContext for?

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

问题描述

作为问题的延续,将DataContext与WPF中的另一个属性



在研究的最后,我很惊讶地发现,当一个人写这样的东西:

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

DataContext $ c>内容属性绑定是标签控制本身!它仍然有效的事实是由于最接近的父级的DataContext值的默认继承。



但是如果您将此标签包装在自定义控件中,而您不想将您的数据绑定到该控件的 DataContext 属性,您将更有可能喜欢:

 <控件:SearchSettings Settings ={Binding Path = Settings}/> 

这里是你。现在,您需要将设置设置为 DataContext SearchSettings 控制,对于 Label 里面绑定,但你不能,因为这将触发重新绑定设置属性



我不明白使用不同来源混合绑定属性的要点: DataContext ,by ElementName
那么为什么我会使用 DataContext

解决方案

当您写

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

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



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



所以假设你有一个窗口。没有设置DataContext,窗口仍然显示,但没有数据。



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



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

 code>< Window x:Name =myWindow> <! -  DataContext设置为ClassA  - > 
< StackPanel> <! - DataContext设置为ClassA - >

<! - DataContext设置为ClassA,因此将显示ClassA.Name - >
< Label Content ={Binding Name}/>

<! - DataContext仍然是ClassA,但是我们将其设置为ClassA.ClassB - >
< StackPanel DataContext ={Binding ClassB}>

<! - DataContext设置为ClassB,因此将显示ClassB.Name - >
< Label Content ={Binding Name}/>

<! - DataContext仍然是ClassB,但我们绑定到Window的DataContext.Name,它是ClassA.Name - >
< Label Content ={Binding ElementName = myWindow,Path = DataContext.Name}/>
< / StackPanel>
< / StackPanel>
< / Window>

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

更新:我从WPF新用户经常看到这个问题,我把这个答案扩展到了我的博客上的一篇文章:这个你说的DataContext是什么?


As a continuation of the question Linking DataContext with another property in WPF.

At the very end of the research I was very surprised to find out that when one writes something like that:

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

The DataContext against which the Content property is binded is of the Label control itself! The fact that it still works is due to the default inheritance of the DataContext value from the nearest parent.

But if you have this label wrapped in a custom control, and you don't want to bind your data to the DataContext property of that control, you would more likely love to have:

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

And here you are. Now you need to set Settings as the DataContext for the SearchSettings control, for Label inside to bind against, but you can't, because that will trigger re-binding of Settings property.

I can't see the point in mixing binding properties using different sources: DataContext, by ElementName, etc. So why would I ever use DataContext?

解决方案

When you write

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

you are binding to myLabel.DataContext.Name, and not myLabel.Name.

The XAML in WPF is just a pretty user interface to display and interact with the actual data, otherwise known as the DataContext. The purpose of other binding sources (RelativeSource, ElementName, etc) is to point to another property that doesn't exist in the current control's DataContext


So suppose you have a Window. Without setting the DataContext, the window still displays but there is no data behind it.

Now suppose to set myWindow.DataContext = new ClassA();. Now the data that the window is displaying is ClassA. If ClassA has a property called Name, I could write a label and bind it to Name (such as your example), and whatever value is stored in ClassA.Name would get displayed.

Now, suppose ClassA has a property of ClassB and both classes have a property called Name. Here is a block of XAML which illustrates the purpose of the DataContext, and an example of how a control would refer to a property not in it's own 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>

As you can see, the DataContext is based on whatever data is behind the UI object.

Update: I see this question so often from new WPF users that I expanded this answer into a post on my blog: What is this "DataContext" you speak of?

这篇关于什么是DataContext?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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