C# 窗口DataContext或ElementName
我目前在指定或不指定窗口的datacontext方面面临一个小问题,以及为什么不同方法之间存在差异。希望你能帮助我 让我们从一些代码开始来说明我的问题。这是我的TestWindow.xaml.cs的代码,没有什么特别之处,只是一个简单的字符串属性C# 窗口DataContext或ElementName,c#,wpf,xaml,C#,Wpf,Xaml,我目前在指定或不指定窗口的datacontext方面面临一个小问题,以及为什么不同方法之间存在差异。希望你能帮助我 让我们从一些代码开始来说明我的问题。这是我的TestWindow.xaml.cs的代码,没有什么特别之处,只是一个简单的字符串属性 public partial class TestWindow : Window { private string _helloWorld = "Hello World!"; public string HelloWorld
public partial class TestWindow : Window
{
private string _helloWorld = "Hello World!";
public string HelloWorld
{
get { return _helloWorld; }
set { _helloWorld = value; }
}
public TestWindow()
{
InitializeComponent();
}
}
以下三种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.)在窗口上指定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>
前两种方法效果不错,但为什么第三种方法失败了呢
在第一个方法中,我没有指定DataContext,它会自动工作;在第二个方法中,我没有指定ElementName,它会工作,但没有声明其中一个失败。为什么它无法自动获取这两个数据,但可以单独获取每一个数据?第三个失败,因为没有推断出
DataContext
。如果你想让第三个工作,你可以这样做:
public TestWindow()
{
InitializeComponent();
this.DataContext = this;
}
它对路径
HelloWorld
一无所知,因为它没有DataContext
第三个失败,因为没有推断DataContext
。如果你想让第三个工作,你可以这样做:
public TestWindow()
{
InitializeComponent();
this.DataContext = this;
}
它对路径
HelloWorld
一无所知,因为它没有DataContext
它在第一种和第二种情况下工作,因为TextBlock
能够找到HelloWorld
属性
在第一种情况下,您指定的是ElemtnName
,因此TextBlock
将引用Window
并在Window类中搜索属性HelloWorld
在第二种情况下,您正在指定窗口的DataContext
,因此Textblock
将继承该属性,并在DataContext
中查找HelloWorld
属性,即再次Window
类
在第三种情况下,您没有指定任何内容,因此TextBlock无法找到HelloWorld
属性
在第一种情况下,我没有指定DataContext,为什么它应该知道 买什么 设置
ElementName
时,TextBlock
将尝试从该元素中查找HelloWorld
在第二种情况下,我没有指定它应该得到什么
您正在设置其父级的
DataContext
,即窗口,这样它会自动继承该窗口,并告诉它从DataContext
中提取HelloWorld
属性,因为TextBlock
能够找到HelloWorld
属性,所以它在第一和第二种情况下工作
在第一种情况下,您指定的是ElemtnName
,因此TextBlock
将引用Window
并在Window类中搜索属性HelloWorld
在第二种情况下,您正在指定窗口的DataContext
,因此Textblock
将继承该属性,并在DataContext
中查找HelloWorld
属性,即再次Window
类
在第三种情况下,您没有指定任何内容,因此TextBlock无法找到HelloWorld
属性
在第一种情况下,我没有指定DataContext,为什么它应该知道
买什么
设置ElementName
时,TextBlock
将尝试从该元素中查找HelloWorld
在第二种情况下,我没有指定它应该得到什么
您正在设置其父级的DataContext
,即窗口
,以便它自动继承该窗口,并告诉它从DataContext
{Binding}
提取HelloWorld
属性。默认情况下,{Binding}
始终引用DataContext
在第一个示例中,您只需使用elementName停用默认行为,这将使用元素作为源
在第二个示例中,您显式地将DataContext
更改为指向窗口
因此,在上一个示例中,{Binding HelloWorld}
尝试将null
转换为具有失败的HelloWorld属性的and对象。{Binding}
默认情况下始终引用数据上下文
在第一个示例中,您只需使用elementName停用默认行为,这将使用元素作为源
在第二个示例中,您显式地将DataContext
更改为指向窗口
因此,在上一个示例中,{Binding HelloWorld}
尝试将null
转换为具有HelloWorld属性的and对象,但该属性失败。请阅读注释。绑定源是要在其上查找由Path
(HelloWorld)指定的属性的对象ElementName
、RelativeSource
和Source
设置绑定源。如果它们为null,则源是要绑定的元素(TextBlock)的DataContext。如果未显式设置元素的DataContext,则它将从包含元素继承
在第一种情况下,任何DataContext都与TextBlock绑定无关,因为源是通过ElementName显式设置的
在第二种情况下,指定源需要DataContext,因为它不是通过ElementName、RelativeSource或source显式设置的。TextBlock的DataContext未设置,因此窗口的DataContext被继承
在第三种情况下,没有显式源,也没有要继承的DataContext,因此源为null,绑定失败。没有默认源。请阅读该源的备注。绑定源是要查找的对象