2016-03-24 4 views
0

私は次の例のようなコードでバインディングを作成すると、すべてが正常に動作します動作しません:私は純粋に結合することを設定しようとすると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> 

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をXAMLで、それは動作しません:

<TextBlock x:Name="NameBlock" Width="120" FontSize="16" Foreground="Red" Text="{Binding Source=Craftsman, Path=Name, Mode=OneWay}"/> 

私はウィンドウの要素のデータコンテキストを設定しても、それは動作しません:

DataContext="{Binding RelativeSource={RelativeSource Self}}" 

私はこの問題を解決しません。 私は理解していますWHYこれはXAMLではDataContextと一緒に、または使用しないで動作しません。

答えて

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}" 

が実際に文字列リテラル「職人」とないあなたのウィンドウのプロパティに結合されることを意味します。あなたのバインディングを使用すると、ウィンドウ

DataContext="{Binding RelativeSource={RelativeSource Self}}" 

そして、あなたの結合のためのDataContextを設定する必要があります仕事を取得するには

(これは愚かである)

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}}" 
+0

しかし、なぜこれがこのように動作していますか?つまり、コードで同じ方法でXAMLで同じバインディングを作成しました。 XAMLでコードが動作する理由は何ですか? XAMLのSourceプロパティ設定の意味は何ですか? – EngineerSpock

+0

コードでは、ソースをCratfsmanタイプのオブジェクトに設定します.xamlではソースを*文字列リテラル* "職人"に設定します。 xamlでSourceを使用する方法の例を追加しました。 –

+0

パスも文字列で初期化されますが、動作します。 Sourceプロパティは私にとって非常に難しいようです。面白いと思うかもしれませんが、私はWPFで5年間働いていて、バインディングを成功させてきましたが、彼らが実際にどのように実際に働いているかを理解するためには、 – EngineerSpock

1

WindowDataContextは正しく設定されていますが、TextBlockのバインディングが間違っています。

あなたのXAMLは次のようになります。

<TextBlock x:Name="NameBlock" Width="120" FontSize="16" Foreground="Red" Text="{Binding Path=Craftsman.Name, Mode=OneWay}"/> 
+0

DataContextを設定すると、Sourceプロパティは無関係になりますか? – EngineerSpock

+0

もう1つの質問は、DataContextを設定せずにSourceを使用できない理由です。 – EngineerSpock

+0

ところで。 'Source'は通常、' DataContext'オブジェクトのメンバーではないものを参照するために使用されます。例については、https://msdn.microsoft.com/en-gb/library/system.windows.data.binding.source(v=vs.110).aspxを参照してください。 'DataContext'はデータソース(' Window'オブジェクト自身か 'ViewModel'クラスかどうか)を' FrameworkElement'バインディングスコープに直接関連付けるものです。 'DataContext'を設定しなければ、バインドするデータスコープはありません。' DataContext'はデフォルトではnullです。 – toadflakz

-1

を使用しています。

  1. あなたはInitializeComponent()後に職人のオブジェクトを作成しているので、それが変更された場合、あなたの窓のdoesntのは知っています。 craftsmanの通知のためにウィンドウクラスにINotifyPropertyChangedを実装します。または、InitializeComponent()の前にオブジェクトを作成します。したがって、ウィンドウが作成される直前にすべてが利用可能になるため、最初のバインディングが機能します。あなたの最初のケースで

  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は値として完全に理解を示していきます。それはInitilizeComponentに関連しています()、変更通知:

  3. あなたのパスが間違っている、それはText="{Binding Path=TheCraftsman.Name, Mode=OneWay}"する必要があり、ソースは、リソース/プロパティ-来-から-要素などから来る値

結論です、あなたのパス。

関連する問題