当我在代码中创建绑定时,如下例所示,一切正常:
public partial class BindingToCustomType : Window {
public Craftsman Craftsman { get; set; }
public BindingToCustomType() {
InitializeComponent();
Craftsman = new Craftsman() {Age = 45, LastName = "Joe", Name = "Grok"};
Binding binding = new Binding();
binding.Source = Craftsman;
binding.Path = new PropertyPath("Name");
NameBlock.SetBinding(TextBlock.TextProperty, binding);
}
XAML:
<Window x:Class="DataBinding.BindingToCustomType"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="Window"
Title="BindingToCustomType">
<TextBlock x:Name="NameBlock" Width="120" FontSize="16" Foreground="Red" />
</Window>
当我尝试纯粹在XAML中设置该绑定时,它不起作用:
<TextBlock x:Name="NameBlock" Width="120" FontSize="16" Foreground="Red" Text="{Binding Source=Craftsman, Path=Name, Mode=OneWay}"/>
即使我在Window元素上设置数据上下文,它也不起作用:
DataContext="{Binding RelativeSource={RelativeSource Self}}"
我不想解决这个问题。 我想理解为什么这在使用DataContext或不使用XAML时不起作用。
答案 0 :(得分:1)
您设置Window
DataContext
是正确的,但TextBlock
上的绑定错误。
您的XAML应该是:
<TextBlock x:Name="NameBlock" Width="120" FontSize="16" Foreground="Red" Text="{Binding Path=Craftsman.Name, Mode=OneWay}"/>
答案 1 :(得分:1)
如果您要查看visual studio中的输出,您会在xaml绑定中找到以下行。
System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''String' (HashCode=538009415)'.
BindingExpression:Path=Name; DataItem='String' (HashCode=538009415); target element is 'TextBlock' (Name='NameBlock'); target property is 'Text' (type 'String')
这意味着
Text="{Binding Source=Craftsman, Path=Name, Mode=OneWay}"
实际上是绑定到字符串文字&#39; Craftsman&#39;而不是你窗户的财产。
要使绑定工作,您需要为窗口设置datacontext
DataContext="{Binding RelativeSource={RelativeSource Self}}"
你的绑定可能是(这是愚蠢的)
Text="{Binding Path=DataContext.Craftsman.Name, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
或者非常简单
Text="{Binding Craftsman.Name, Mode=OneWay}"
您可以为窗口设置资源
<Window.Resources>
<wpfApplication2:Craftsman x:Key="CraftsmanResource" Age="45" LastName="Joe" Name="Grok"/>
</Window.Resources>
然后使用绑定
Text="{Binding Path=Name, Mode=OneWay, Source={StaticResource CraftsmanResource}}"
答案 2 :(得分:-1)
有几点需要注意。
您正在InitializeComponent()
之后创建工匠对象,因此您的窗口不知道它是否已更改。在您的窗口类中实施INotifyPropertyChanged
以获取craftsman
的通知。或者,在InitializeComponent()
之前创建您的对象。因此,在创建Window之前一切都可用,因此第一次绑定将起作用。
在第一种情况下,请执行此操作
Craftsman = new Craftsman() { Age = 45, LastName = "Joe", Name = "Grok" };
Binding binding = new Binding();
binding.Source = TheCraftsman;
binding.Path = new PropertyPath("Name");
NameBlock.SetBinding(TextBlock.TextProperty, binding);
Craftsman = new Craftsman() { Age = 45, LastName = "Joe", Name = "NewGrok" };
TextBlock将继续将Grok显示为值。
您的路径错误,应该是Text="{Binding Path=TheCraftsman.Name, Mode=OneWay}"
,Source来自资源/属性来自元素等的值。
结论:它与InitilizeComponent(),更改通知和路径有关。