代码之家  ›  专栏  ›  技术社区  ›  Josh G

复杂路径的绑定目标何时更新?

  •  3
  • Josh G  · 技术社区  · 16 年前

    在WPF中使用数据绑定时,当通过 INotifyPropertyChanged 界面

    例如:

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

    无论何时,文本字段都将更改以正确反映SomeField的值 PropertyChanged(this, new PropertyChangedEventArgs("SomeField"))

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

    文本字段是否会更新 PropertyChanged(this, new PropertyChangedEventArgs("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 回复  |  直到 16 年前
        1
  •  3
  •   Josh G    16 年前

    经过进一步调查,当复杂路径的任何部分发送更改通知时,绑定似乎会更新。因此,如果源对象或中间对象被更改,绑定将被更新。

    我建立了一个类似Jared的测试项目:

    <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
  •  0
  •   JaredPar    16 年前

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