When is target binding updated for complex paths?

When using data binding in WPF, the target dependency object is updated when it is notified that the source has been changed through the interface INotifyPropertyChanged.

For example:

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

The text box will change to correctly reflect the value of SomeField when PropertyChanged(this, new PropertyChangedEventArgs("SomeField"))called from the source.

What if I use the complex path as follows:

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

Will the text box be updated for PropertyChanged(this, new PropertyChangedEventArgs("SomeObjField"))in the source?

What about PropertyChanged(this, new PropertyChangedEventArgs("AnotherField"))an intermediate object (an object contained in SomeObjField)?

Source objects and fields are NOT objects or dependency properties! Assume property / classes are implemented something like this:

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()
      }
   }
}
+3
2

, - , . , , .

, , Jared's:

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

, .

+2

100%, PropertyChanged. - , 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

Source: https://habr.com/ru/post/1705786/


All Articles