2009-04-02 7 views
3

WPFでデータバインディングを使用する場合、ソースがINotifyPropertyChangedインターフェイスで変更されたことが通知されると、ターゲット依存オブジェクトが更新されます。例えば複雑なパスの場合、バインディングターゲットはいつ更新されますか?

<TextBlock Text="{Binding Path=SomeField}"/> 

テキストフィールドが正しくPropertyChanged(this, new PropertyChangedEventArgs("SomeField"))がソースから呼び出されるたびSomeFieldの値を反映するために変更されます。

<TextBlock Text="{Binding Path=SomeObjField.AnotherField}"/> 

テキストフィールドをソースにPropertyChanged(this, new PropertyChangedEventArgs("SomeObjField"))のために更新されます:私は、次のような複雑なパスを使用する場合、どのよう

中間オブジェクト(SomeObjFieldに含まれるオブジェクト)については、PropertyChanged(this, new PropertyChangedEventArgs("AnotherField"))はどうなりますか?

ソースオブジェクトおよびフィールドは、依存オブジェクトまたはプロパティではありません。プロパティ/クラスは、次のようなものを実装していると仮定します。

public class Data : INotifyPropertyChanged 
{ 
    // INotifyPropertyChanged implementation... 

    public string SomeField 
    { 
     get { return val; } 
     set 
     { 
     val = value; 
     // fire PropertyChanged() 
     } 
    } 

    public SubData SomeObjField 
    { 
     get { return val; } 
     set 
     { 
     val = value; 
     // fire PropertyChanged() 
     } 
    } 
} 

public class SubData : INotifyPropertyChanged 
{ 
    // INotifyPropertyChanged implementation... 

    public string AnotherField 
    { 
     get { return val; } 
     set 
     { 
     val = value; 
     // fire PropertyChanged() 
     } 
    } 
} 

答えて

2

が、それはときと思われるクラスを策定しました複合パスの任意の部分が、バインディングが更新されるという変更通知を送信します。したがって、ソースオブジェクトまたは中間オブジェクトが変更された場合、バインディングは更新されます。

<StackPanel Name="m_panel"> 
    <TextBox IsReadOnly="True" Text="{Binding Path=SomeObjField.AnotherField }" /> 
    <TextBox x:Name="field1"/> 
    <Button Click="Button1_Click">Edit Root Object</Button> 
    <TextBox x:Name="field2"/> 
    <Button Click="Button2_Click">Edit Sub Object</Button> 
</StackPanel> 

そして、背後にあるコード:

public Window1() 
{ 
    InitializeComponent(); 
    m_panel.DataContext = new Data(); 
} 

private void Button1_Click(object sender, RoutedEventArgs e) 
{ 
    Data d = m_panel.DataContext as Data; 
    d.SomeObjField = new SubData(field1.Text); 
} 

private void Button2_Click(object sender, RoutedEventArgs e) 
{ 
    Data d = m_panel.DataContext as Data; 
    d.SomeObjField.AnotherField = field2.Text; 
} 

私は疑問に提供されている基本的なデータの実装を使用しています

私はジャレッドのようなテストプロジェクトを構築しました。

0

私はあなたの質問の一部にPropertyChangedを求めたものではない100%確信しています。しかし、関連するプロパティがすべてDependencyPropertyのバックアップされたプロパティである場合、これは期待どおりに機能するはずです。私は、次の例

Window1.xaml

<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <StackPanel Name="m_panel"> 
     <TextBlock Text="{Binding Path=SomeField}" /> 
     <TextBlock Text="{Binding Path=SomeField.AnotherField }" /> 
     <Button Click="Button_Click">Update Root Object</Button> 
     <Button Click="Button_Click_1">Update Another Field</Button> 
    </StackPanel> 
</Window> 

Window1.xaml.cs

public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent(); 
     m_panel.DataContext = new Class1(); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     ((Class1)m_panel.DataContext).SomeField = new Class2(); 
    } 

    private void Button_Click_1(object sender, RoutedEventArgs e) 
    { 
     ((Class1)m_panel.DataContext).SomeField.AnotherField = "Updated field"; 
    } 
} 

そして

さらに調査した後
public class Class1 : DependencyObject 
{ 
    public static DependencyProperty SomeFieldProperty = DependencyProperty.Register(
     "SomeField", 
     typeof(Class2), 
     typeof(Class1)); 

    public Class2 SomeField 
    { 
     get { return (Class2)GetValue(SomeFieldProperty); } 
     set { SetValue(SomeFieldProperty, value); } 
    } 

    public Class1() 
    { 
     SomeField = new Class2(); 
    } 
} 

public class Class2 : DependencyObject 
{ 
    public static DependencyProperty AnotherFieldProperty = DependencyProperty.Register(
     "AnotherField", 
     typeof(string), 
     typeof(Class2)); 

    public string AnotherField 
    { 
     get { return (string)GetValue(AnotherFieldProperty); } 
     set { SetValue(AnotherFieldProperty, value); } 
    } 

    public Class2() 
    { 
     AnotherField = "Default Value"; 
    } 
} 
+0

ターゲットプロパティ(この場合はTextBlock.Text)のみが依存関係プロパティと見なすことができます。 SomeField、SomeObjField、およびAnotherFieldはそうではありません。そうであれば、INotifyPropertyChangedインタフェースを実装する必要はありません。 –

+0

ポストに感謝します。私はあなたの例に従い、簡単なテストプロジェクトを作成しました。誰かが頭の上から答えを知ることを望んでいた。 –

関連する問題