2009-04-02 2 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

게시물 주셔서 감사합니다. 나는 당신의 모범을 따르고 간단한 테스트 프로젝트를 만들었다. 나는 누군가가 그들의 머리 꼭대기에서 답을 알기를 바랬다. –

관련 문제