【问题标题】:Binding to ExpandoObject. PropertyChanged not working绑定到 ExpandoObject。属性更改不起作用
【发布时间】:2012-11-17 05:23:19
【问题描述】:

在我的 Windows 应用商店应用程序中,我有一个填充了 ExpandoObjects 的列表。数据绑定适用于初始值,但不适用于我在下载文件后异步设置的图像属性:

public static async void Set<T>(this ExpandoObject thisObject, string property, Func<Task<T>> setter) {
        var expando = thisObject as IDictionary<string, Object>;

        if (!expando.ContainsKey(property)) {
            expando.Add(property, null);
        }
        expando[property] = await setter.Invoke();
    }

连接到 ExpandoObject 上的 PropertyChanged 事件确认它已针对所有对象触发。 新属性附加到对象上,值正确,但ListView中的项目没有全部更新。

该列表包含 14 个对象。如果我使用常规类型的对象而不是 ExpandoObjects 并使用图像属性的相同异步设置,则 14 个对象中的一些会在视图中更新(当前不可见的对象)。如果我在类中实现 INotifyPropertyChanged,则所有 14 个都会更新。 使用 ExpandoObjects 我得到了与没有 INPC 的类型对象的确切行为:更新当前不可见的项目。

因此,PropertyChanged 似乎不适用于 ExpandoObject 和数据绑定。

它在 WPF 中按预期工作,但在商店应用程序中却没有。看比较: https://sites.google.com/site/moramatte/ExpandoComparison.zip?attredirects=0&d=1

【问题讨论】:

标签: .net dynamic binding expandoobject


【解决方案1】:

他们没有添加绑定到动态对象的默认机制,而是添加了一个新接口ICustomTypeProvider。并且该接口也没有添加到 ExpandoObject,但是使用 expando,您应该能够使用索引器绑定,因为它是实现 INotifyPropertyChangedIDictionary&lt;string, object&gt;

<TextBlock Text="{Binding [Foo]}"/>

【讨论】:

    【解决方案2】:

    再次回顾这一点,我得出结论,在使用 ExpandoObjects 时,绑定不适用于 WinRT/Win10(Build 10240)的属性更新(使用 INotifyPropertyChanged 处理的)。

    INotifyCollectionChanged 有效 - 因此 ExpandoObjects 列表会随着它们的变化而更新 - 但它们的属性没有被 Binding 正确连接。

    一种解决方法是创建一个值对象并将其保存在每个 expandoobject 属性中:

    public class ValueHolder : INotifyPropertyChanged
    {
    
      public ValueHolder(object v)
      {
        _value = v;
      }
      public event PropertyChangedEventHandler PropertyChanged;
    
      private object _value;
      public object Value
      {
        get { return _value; }
        set {
          if (_value != value)
          {
            _value = value;
            if (PropertyChanged != null)
            {
              PropertyChanged(this, new PropertyChangedEventArgs("Value"));
            }
          }
        }
      }
    }
    

    然后我可以成功绑定并从 expandoobjects 中的属性获取更新,如下所示:

    <TextBlock   Text='{Binding Path=Attribute1.Value }' MinWidth='20'/>
    

    我这样分配新属性:

    (theList[0] as dynamic).Attribute1 = new ValueHolder("a1");
    

    我像这样更新属性:

    var listitem = (thelist[0] as dynamic);
      listitem.Attribute1.Value = "UPDATE";
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-24
      • 2015-01-04
      • 1970-01-01
      • 1970-01-01
      • 2020-03-03
      • 2017-08-26
      相关资源
      最近更新 更多