Window DataContext或ElementName

时间:2013-08-19 12:18:04

标签: c# wpf xaml

我目前在指定或不指定窗口的datacontext时面临一个小问题,以及为什么各种方法之间存在差异。希望你能帮助我。

让我们从一些代码开始,以显示我的问题。这是我的TestWindow.xaml.cs背后的代码,没有什么特别的,只是一个简单的字符串属性

public partial class TestWindow : Window
{
    private string _helloWorld = "Hello World!";

    public string HelloWorld
    {
        get { return _helloWorld; }
        set { _helloWorld = value; }
    }

    public TestWindow()
    {
        InitializeComponent();
    }
}

此代码对于以下所有3个XAML布局都是相同的,因此代码后面的修改只在XAML中有效。

1。)使用给定的ElementName

进行数据绑定
<Window x:Class="Ktsw.Conx.ConxClient.TestWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="TestWindow" Height="300" Width="300"
        Name="TestWin">
    <Grid>
        <TextBlock Text="{Binding HelloWorld, ElementName=TestWin}"></TextBlock>
    </Grid>
</Window>

2。)在Window

上使用指定的DataContext进行数据绑定
<Window x:Class="Ktsw.Conx.ConxClient.TestWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="TestWindow" Height="300" Width="300"
        DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
        <TextBlock Text="{Binding HelloWorld}"></TextBlock>
    </Grid>
</Window>

3.。)既不是ElementName也不是指定DataContext

<Window x:Class="Ktsw.Conx.ConxClient.TestWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="TestWindow" Height="300" Width="300">
    <Grid>
        <TextBlock Text="{Binding HelloWorld}"></TextBlock>
    </Grid>
</Window>

前两种方法工作正常,但为什么第3次失败?

在第一种方法中,我没有指定DataContext并且它自动工作,在第二种方法中,我没有指定ElementName并且它可以工作,但是没有声明其中一个失败。为什么它会自动失败,但是单独获取每个都可以正常工作?

4 个答案:

答案 0 :(得分:2)

阅读Binding.Source property的备注。绑定源是查找Path(HelloWorld)指定的属性的对象。 ElementNameRelativeSourceSource设置绑定源。如果它们为null,则源是您要绑定的元素的DataContext(TextBlock)。如果未显式设置元素的DataContext,则它继承自包含元素。

在第一种情况下,任何DataContext都与TextBlock绑定无关,因为源是通过ElementName显式设置的。

在第二种情况下,需要DataContext来指定源,因为它没有通过ElementName,RelativeSource或Source显式设置。未设置TextBlock的DataContext,因此继承了Window。

在第三种情况下,没有显式的源和没有DataContext可以继承,因此源为null并且绑定失败。没有默认来源。

答案 1 :(得分:1)

它正在第1和第2种情况下工作,因为TextBlock能够找到HelloWorld属性

在第一种情况下,您指定了ElemtnName,因此TextBlock将引用Window并在Window类中搜索属性HelloWorld

在第二种情况下,您指定了DataContext的窗口,因此Textblock将继承该窗口并在HelloWorld中查找DataContext属性,即Window类< / p>

在第三种情况下,您没有指定任何内容,因此TextBlock无法找到HelloWorld属性

  

在第一种情况下,我没有指定DataContext,为什么它应该知道   该怎么办?

当您设置ElementName时,TextBlock会尝试从该元素中找到HelloWorld

  

在第二种情况下,我没有说明它应该得到什么?

您正在设置DataContext的父Window,因此它会自动继承该内容,并且您告诉它从HelloWorld中提取DataContext属性

答案 2 :(得分:1)

默认情况下,

{Binding}始终引用DataContext

在第一个示例中,您只需使用elementName停用默认行为,然后使用该元素作为源。

在第二个示例中,您明确地将DataContext更改为指向您的窗口。

因此,在最后一个示例中,{Binding HelloWorld}尝试将null转换为具有失败的HelloWorld属性的Object。

答案 3 :(得分:0)

第三个失败是因为DataContext未被推断。如果你想让第三个工作,你会做这样的事情:

public TestWindow()
{
    InitializeComponent();

    this.DataContext = this;
}

它不知道关于路径HelloWorld任何,因为它没有DataContext