在我的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中按预期工作,但不能在Store App中使用。看比较: https://sites.google.com/site/moramatte/ExpandoComparison.zip?attredirects=0&d=1
答案 0 :(得分:1)
他们没有添加绑定到动态对象的默认机制,而是添加了一个新接口ICustomTypeProvider
。并且该接口也没有添加到ExpandoObject,但是使用expando,您应该能够使用索引器绑定,因为它是IDictionary<string, object>
,它实现了INotifyPropertyChanged
。
<TextBlock Text="{Binding [Foo]}"/>
答案 1 :(得分: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";