WPF:什么会导致绑定源无法更新? [英] WPF: What can cause a binding source to not be updated?

查看:89
本文介绍了WPF:什么会导致绑定源无法更新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到无法确定如何调试的情况。我希望有人可以提出建议,为什么它可能无法正常工作,并向正确的方向指出。

I have a situation I'm not sure how to debug. I'm hoping someone can suggest why it might not be working and point me in the right direction.

我有一个来自TIFF图像的数据库,该图像公开为属性 System.Data.Linq.Binary 类型。我想在 ItemsControl 中显示该TIFF图像的各个帧,所以我编写了一个转换器,该转换器采用Binary数据类型并返回 ObservableCollection 的BitmapFrames。我使用转换器以及 Mode = TwoWay 和<$将 ItemsControl.ItemsSource 绑定到Binary属性。 c $ c> UpdateSourceTrigger = PropertyChanged 。

I have a TIFF image from a database which is exposed as a property of type System.Data.Linq.Binary. I want to display the individual frames from that TIFF image in an ItemsControl so I've written a converter that takes the Binary datatype and returns an ObservableCollection of BitmapFrames. I'm binding ItemsControl.ItemsSource to the Binary property using the converter along with "Mode=TwoWay" and "UpdateSourceTrigger=PropertyChanged".

图像显示正常。问题是,如果我将一个框架添加到集合中,则显示会更新,但是更改不会转移回源对象中的Binary属性。从未调用过转换器中的 ConvertBack()方法(这向我表明该绑定甚至从未尝试更新源代码)。如果我手动调用 BindingExpression.UpdateSource(),就像它是为 UpdateSourceTrigger = Explicit 设置的一样二进制属性确实可以正确更新。

The display of the images is working fine. The problem is that if I add a frame to the collection the display updates, but that change is not transferred back to the Binary property in the source object. The ConvertBack() method in my converter is never called (indicating to me that the binding is never even trying to update the source). If I manually make a call to BindingExpression.UpdateSource() as if it were set for "UpdateSourceTrigger=Explicit" the Binary property does update correctly.

因此,如果为 Mode = TwoWay 和<$ c设置了绑定$ c> UpdateSourceTrigger = PropertyChanged 并且该对象实现 INotifyPropertyChanged ObserverableCollection 会执行),为什么绑定实际上不尝试更新源代码?

So if a binding is set for "Mode=TwoWay" and "UpdateSourceTrigger=PropertyChanged" and the object implements INotifyPropertyChanged (which ObserverableCollection does), why doesn't the binding actually try to update the source?

谢谢!

推荐答案

之所以发生这种情况,是因为对于TwoWay绑定,WPF仅检测属性何时获得新值,而不检测属性引用的对象何时更改。

This is happening because for TwoWay bindings, WPF only detects when the property gets a new value, not when an object referenced by the property changes.

在您的情况下,您的属性包含您的转换器创建的ObservableCollection。尽管ObservableCollection的内容已被修改,并激发了INotifyPropertyChanged,但绑定属性本身并未更改:它仍然引用与以前相同的ObservableCollection。因此,不会触发WPF DataBinding,也不会更新您的源。

In your case your property contains the ObservableCollection created by your converter. Although the contents of the ObservableCollection has been modified, and it fires INotifyPropertyChanged, the bound property itself has not changed: It still refrences the same ObservableCollection as before. Because of this, WPF DataBinding is not triggered and your source is not updated.

手动调用UpdateSource()时,它将强制ObservableCollection通过转换器传递,并且返回到数据对象,因此它可以正常工作。

When you call UpdateSource() manually, it forces the ObservableCollection to be passed through your converter and back to your data object, so it works.

获得所需行为的最简单方法是:

The easiest way to get the behavior you desire is:


  1. 而不是绑定到数据字段,而是绑定到数据对象,然后在转换器中提取所需的字段(如果要使通用转换器可以访问任何字段,请传递

  1. Instead of binding to the data field, bind to the data object, and extract the desired field in the converter (if you want to make a generic converter that can access any field, pass the field as a parameter).

在转换器中,当构造ObservableCollection时,添加一个CollectionChanged事件,该事件在每次触发时都会更新原始对象。

In the converter when you construct the ObservableCollection, add a CollectionChanged event that updates the original object whenever it fires.

以下是代码中的基本概念:

Here is the general idea in code:

  public MyConverter : IValueConverter
  {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
      PropertyInfo property = object.GetType().GetProperty((string)parameter);

      var coll = BinaryToCollection((Binary)property.GetValue(object, null));

      coll.CollectionChanged += (sender, e) =>
      {
        property.SetValue(object, CollectionToBinary(coll));
      };
      return coll;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
      throw new NotImplementedException();
    }

    private ObservableCollection<SomeType> BinaryToCollection(Binary data)
    {
      // conversion details here
    }

    private Binary CollectionToBinary(ObservableCollection<SomeType> coll)
    {
      // conversion details here
    }

  }

在这种情况下,您的绑定将从

In this case your binding would change from

 <ItemsControl ItemsSource="{Binding something.property, Mode=TwoWay, Converter={...}}"

  <ItemsControl ItemsSource="{Binding something, Converter={...}}"

,转换器参数为属性名称

with the converter parameter being the property name

希望这会有所帮助!

这篇关于WPF:什么会导致绑定源无法更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆