从XAML绑定不起作用

时间:2016-03-24 10:54:52

标签: c# wpf xaml data-binding

当我在代码中创建绑定时,如下例所示,一切正常:

 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时不起作用。

3 个答案:

答案 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)

有几点需要注意。

  1. 您正在InitializeComponent()之后创建工匠对象,因此您的窗口不知道它是否已更改。在您的窗口类中实施INotifyPropertyChanged以获取craftsman的通知。或者,在InitializeComponent()之前创建您的对象。因此,在创建Window之前一切都可用,因此第一次绑定将起作用。

  2. 在第一种情况下,请执行此操作

            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显示为值。

  3. 您的路径错误,应该是Text="{Binding Path=TheCraftsman.Name, Mode=OneWay}",Source来自资源/属性来自元素等的值。

  4. 结论:它与InitilizeComponent(),更改通知和路径有关。