wpf DataContext 有什么用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7262137/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:03:13  来源:igfitidea点击:

What is DataContext for?

wpfdata-binding

提问by Eugene Strizhok

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

作为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 DataContextagainst which the Contentproperty is binded is of the Labelcontrol itself! The fact that it still works is due to the default inheritance of the DataContext value from the nearest parent.

DataContext其对Content性能的绑定是的Label控制本身!它仍然有效的事实是由于从最近的父级继承了 DataContext 值的默认值。

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

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

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

And here you are. Now you need to set Settingsas the DataContextfor the SearchSettingscontrol, for Labelinside to bind against, but you can't, because that will trigger re-binding of Settingsproperty.

你来了。现在,你需要设置SettingsDataContextSearchSettings控制,对Label内部反对绑定,但你不能,因为这将触发的重新绑定Settings属性。

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

我看不出使用不同来源混合绑定属性的意义:DataContext、 byElementName等。那我为什么要使用DataContext

回答by Rachel

When you write

当你写

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

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

您绑定到myLabel.DataContext.Name,而不是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

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



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

Now suppose to set myWindow.DataContext = new ClassA();. Now the data that the window is displaying is ClassA. If ClassAhas 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.Namewould get displayed.

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

Now, suppose ClassAhas a property of ClassBand 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

现在,假设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>

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

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

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?

更新:我经常从新的 WPF 用户那里看到这个问题,因此我将这个答案扩展到我博客上的一篇文章中:你说的这个“DataContext”是什么?

回答by Cornel Marian

From CodeProjectby kishore Gaddam:

CodeProject上由纪Gaddam:

DataContextis one of the most fundamental concepts in Data Binding. The Binding object needs to get its data from somewhere, and there are a few ways to specify the source of the data like using Source property directly in the Binding, inheriting a DataContextfrom the nearest element when traversing up in the tree, setting the ElementNameand RelativeSourceproperties in the Binding object.

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

Detailed example on CodeProject: http://www.codeproject.com/Articles/321899/DataContext-in-WPF

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

回答by CodeNaked

In that particular case, you could do:

在这种特殊情况下,您可以执行以下操作:

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

Assuming you want everything that may be content of the SearchSettings to use Settings as it's data context. Basically, the DataContext affects the element itself an any descendants that don't explicitly override it.

假设您希望 SearchSettings 的所有内容都使用 Settings 作为数据上下文。基本上,DataContext 会影响元素本身以及未显式覆盖它的任何后代。

回答by H.B.

In most cases you dowant to bind to the DataContext, in some templates on ItemsControls it is the only way to bind to the currently templated item for example. Further bindings to the DataContext are nice to write and read as they are concise.

在大多数情况下,您确实希望绑定到 DataContext,例如,在 ItemsControls 上的某些模板中,它是绑定到当前模板项的唯一方法。与 DataContext 的进一步绑定很容易编写和阅读,因为它们很简洁。

In your example you can still set the DataContext, you only need to modify the binding on the Settings respectively:

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

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