31

在我的 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

4

2 回答 2

1

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

<TextBlock Text="{Binding [Foo]}"/>
于 2015-03-22T23:07:18.990 回答
0

再次回顾这一点,我得出结论,在使用 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";
于 2016-03-18T08:05:45.137 回答