【问题标题】:Binding to object itself, doesn't update when individual property changes绑定到对象本身,当单个属性更改时不会更新
【发布时间】:2020-02-09 18:46:07
【问题描述】:

在一个列表框中,我有一个包含许多属性的对象列表,由于我一次渲染所有对象以及它的通用对象,我绑定到对象本身。

<local:ItemRenderer ItemReference="{Binding Path=."}/>

问题是当底层对象更新属性之一时,OnPropertyChanged 不会触发绑定更新。有没有办法在任何属性更改时触发绑定更新?

一个想法是拥有一个仅用于通知的属性,但底层 ObservableCollection 是 Object 类型,添加 BindingNotifier="{Binding Path=BindingNotifier"} 无法识别并且不起作用。

编辑

这似乎是一个很好的解决方案,但它不起作用

public class MyObject : INotifyPropertyChanged {
    public MyObject Self
    {
        get { return this; }            
    }

那我试试绑定

<local:ItemRenderer ItemReference="{Binding Self"}/>

这适用于初始绑定,但调用

OnPropertyChanged("Self");

不更新对象。

【问题讨论】:

    标签: c# .net wpf xaml data-binding


    【解决方案1】:

    将控件或视图或页面的数据上下文或全部重置null,然后将其交换回最近更改的实例。 将其更改为相同的引用不起作用...一个需要两个步骤


    这里是实际代码,由于在类似情况下更新视图控件的命令(从 VM 执行以保持 VM 和视图操作分开)更改,我需要以相同的方式触发控件。

    同样的情况发生在下面的代码中,通知更改的单个属性没有更新CurrentBatch 上的整个实例绑定。必须更新其他控件以表示 CurrentBatch 的某些内容发生了变化......

    public MainWindow()
    {
        DataContext = VM = new CertifyingVM();
    
        VM.CommandRefreshBindings = new OperationCommand(o =>
        {
            MainAccessionHeader.DataContext =
            MainHeader.DataContext = null;
    
            MainAccessionHeader.DataContext =
            MainHeader.DataContext = VM;
    
            var currentBatch = VM.CurrentBatch;
            MainAccessionHeader.CurrentBatch = null;
            MainAccessionHeader.CurrentBatch = currentBatch;
    
        });
    
        VM.LockBatchGui = new OperationCommand(o =>
        { ... }
    

    OperationCommand 是我的ICommand 操作,在我题为Xaml: MVVM Example for Easier Binding 的博文中进行了演示。

    如何触发它取决于你,只需将 datacontext 的值删除为 null 然后将其设置回来。

    【讨论】:

      【解决方案2】:

      您可以使用IMultiValueConverter 实现并绑定到对象本身和在对象的任何属性更改时更改的属性:

      public class TheConverter : IMultiValueConverter
      {
          public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
          {
              return values[0]; //return the actual object
          }
      
          public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
          {
              throw new NotSupportedException();
          }
      }
      

      XAML:

      <local:ItemRenderer>
          <local:ItemRendered.ItemsReference>
              <MultiBinding>
                  <MultiBinding.Converter>
                      <local:TheConverter />
                  </MultiBinding.Converter>
                  <Binding Path="." />
                  <Binding Path="BindingNotifier" />
              </MultiBinding>
          </local:ItemRendered.ItemsReference>
      </local:ItemRenderer>
      

      这要求您在修改对象的任何属性时设置BindingNotifier 属性。另一种选择是为每个属性添加一个&lt;Binding&gt; 元素。

      【讨论】:

      • 这是一个非常有用的答案。我将不得不使用这个和我的答案来为这个场景设计一个混合操作。
      猜你喜欢
      • 1970-01-01
      • 2014-08-10
      • 1970-01-01
      • 2013-05-01
      • 2011-09-19
      • 2019-03-24
      • 1970-01-01
      • 1970-01-01
      • 2020-04-08
      相关资源
      最近更新 更多