.net - generic - Enlazando a ExpandoObject. PropertyChanged no funciona
dynamicobject (2)
No agregaron un mecanismo predeterminado para vincular objetos dinámicos y en su lugar agregaron una nueva interfaz ICustomTypeProvider
. Y esa interfaz tampoco se agregó a un ExpandoObject, pero con expando debería poder usar el enlace del indexador, ya que es un IDictionary<string, object>
que implementa INotifyPropertyChanged
.
<TextBlock Text="{Binding [Foo]}"/>
En mi aplicación de la Tienda Windows, tengo una lista poblada con ExpandoObjects. El enlace de datos funciona bien para los valores iniciales, pero no para una propiedad de imagen que establecí asincrónicamente después de que se descargó un archivo:
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();
}
Conectarse al evento PropertyChanged en el ExpandoObject confirma que está activado para todos los objetos. La nueva propiedad se adjunta al objeto y el valor es correcto, pero los elementos en el ListView no se actualizan por completo.
La lista contiene 14 objetos. Si utilizo objetos de tipo normal en lugar de ExpandoObjects y utilizo la misma configuración de sincronización de la propiedad de la imagen, algunos de los 14 objetos se actualizan en la vista (los que no están visibles actualmente). Si implemento INotifyPropertyChanged en la clase, todos los 14 se actualizan. Usando ExpandoObjects obtengo el comportamiento exacto como con los objetos tipeados sin INPC: los elementos que no están actualmente visibles se actualizan.
Parece que PropertyChanged no está trabajando con ExpandoObject y el enlace de datos.
Funciona según lo previsto en WPF, pero no en una aplicación de tienda. Ver comparación: https://sites.google.com/site/moramatte/ExpandoComparison.zip?attredirects=0&d=1
Repasando esto de nuevo, concluyo que el enlace no funciona para actualizaciones de atributos (las que se manejan con INotifyPropertyChanged) para WinRT / Win10 (Build 10240) cuando se usa ExpandoObjects.
Trabajos de INotifyCollectionChanged: para que las listas de ExpandoObjects se actualicen a medida que cambian, pero sus propiedades no están conectadas correctamente por Binding.
Una solución alternativa es crear un objeto de valor y mantenerlo en cada propiedad 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"));
}
}
}
}
}
A continuación, puedo vincular y obtener actualizaciones de las propiedades en expandoobjetos como este:
<TextBlock Text=''{Binding Path=Attribute1.Value }'' MinWidth=''20''/>
Asigno nuevas propiedades como esta:
(theList[0] as dynamic).Attribute1 = new ValueHolder("a1");
Actualizo propiedades como esta:
var listitem = (thelist[0] as dynamic);
listitem.Attribute1.Value = "UPDATE";