WPF数据绑定到代码后台中的标准CLR属性

3

我正在学习WPF数据绑定,但我对其中的某些部分还不理解。我在StackOverflow上看到了一些类似的问题,但我仍然无法确定自己做错了什么。

我有一个简单的Person类,其中包含Firstname和Surname属性(标准CLR属性)。我的Window类上也有一个标准CLR属性,用于公开Person实例。

然后我有一些XAML代码,其中有两种绑定方法。第一种方法有效,第二种方法无效。有人能帮我理解为什么第二种方法失败吗?输出日志中没有绑定错误消息。

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="Window1" Height="300" Width="300"
    DataContext="{Binding RelativeSource={RelativeSource Self}, Path=MyPerson}">
<StackPanel>
    <Label>My Person</Label>
    <WrapPanel>
        <Label>First Name:</Label>
        <Label Content="{Binding RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}, Path=MyPerson.FirstName}"></Label>
    </WrapPanel>
    <WrapPanel>
        <Label>Last Name:</Label>
        <Label Content="{Binding MyPerson.Surname}"></Label>
    </WrapPanel>
</StackPanel>

编辑:好的,到目前为止谢谢。我把第二个表达式改成了:

<Label Content="{Binding Surname}"></Label>

但我仍然无法使它正常工作!


1
尝试添加此命名空间xmlns:diag=”clr-namespace:System.Diagnostics;assembly=WindowsBase”,并在绑定中添加diag:PresentationTraceSources.TraceLevel=High以查看绑定错误。您的绑定应该像Content="{Binding Surname, diag:PresentationTraceSources.TraceLevel=High}"这样。 - Craig Suchanec
每当您遇到数据绑定错误时 - 不,划掉,每当您调试任何使用数据绑定的WPF应用程序时 - 您都应该打开VS的输出窗口并将其显示在屏幕上,以便您可以看到绑定在不工作时写入其中的许多错误消息。 - Robert Rossney
1
这个问题的标题应该是正确的,读作“在XAML中将WPF DataBinding绑定到标准CLR属性”。在代码后台绑定是一个完全不同的问题。 - kpozin
4个回答

2
好的,我发现了问题所在。我对WPF还不熟悉,所以花了一段时间才找到解决方法。
在代码后台中,我是在调用InitializeComponent之后设置MyPerson属性的。
第一种方法有效,因为窗口已经初始化并且MyPerson属性已经设置好了,此时标签也已经初始化并且数据绑定表达式已经被评估。
第二种方法无效,因为当窗口和相关的DataContext被初始化时,MyPerson属性还没有被设置。
当你知道了如何做,就很简单!

1
要让第二种方法起作用,你只需要:
<Label Content="{Binding Surname}"/>

因为您已经将DataContext设置为窗口元素顶部的person。

顶部的DataContext对我有用,但是除非我有一个包含数据的单独类,否则绑定不会在设计器中显示。要使此工作正常,您需要执行以下操作:

<Window.Resources>
    <local:BindingClass x:Key="bindingClass"/>
</Window.Resources>
<Grid DataContext="{StaticResource bindingClass.MyPerson}">
    <Label Content="{Binding Surname}"/>
</Grid>

这需要您创建一个单独的类(在本例中称为BindingClass),其中包含MyPerson属性。

我认为这在设计器中可以工作,因为我在xaml中明确地创建了该类的新实例。


啊,谢谢,我明白了。我想那只是我在来回更改时打错的一个笔误。如果我删除MyPerson限定符,它仍然无法工作。 - Matt B
关于 {Binding Path=Surname} 呢? - Adam Driscoll
也尝试过了。我认为问题在于我声明DataContext的方式上。只是不确定具体哪里出了问题.... - Matt B

1
首先,除非您在该绑定上设置诊断,否则大多数情况下您不会看到绑定错误。第二个不起作用的原因是您已将DataContext设置为MyPerson。由于这是DataContext,您只需要绑定到Surname属性即可。现在的方式是尝试调用MyPerson.MyPerson.Surname。

0

另一种处理第一个绑定的简单方法是给您的窗口命名,并在绑定中通过 ElementName 引用它:

<Window x:Class="WpfApplication1.Window1"
    Name="MyWindow"
    ...>
<StackPanel>
    <Label>My Person</Label>
    <WrapPanel>
        <Label>First Name:</Label>
        <Label Content="{Binding Path=MyPerson.FirstName, ElementName=MyWindow}"></Label>
    </WrapPanel>
    <WrapPanel>
        <Label>Last Name:</Label>
        <Label Content="{Binding MyPerson.Surname}"></Label>
    </WrapPanel>
</StackPanel>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接