31

In my Windows Store app I have a list populated with ExpandoObjects. Data binding works fine for the initial values, but not for an image property I set asyncronously after a file has been downloaded:

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();
    }

Hooking up to the PropertyChanged event on the ExpandoObject confirms that it is fired for all objects. The new property is attached to the object and the value is correct, but the items in the ListView are not updated in full.

The list contains 14 objects. If I use regular typed objects instead of ExpandoObjects and use the same async setting of the image property, some of the 14 objects gets updated in the view (the ones not currently visible). If I implement INotifyPropertyChanged in the class all 14 gets updated. Using ExpandoObjects I get the exact behaviour as with the typed objects without INPC: items not currently visible are updated.

So it seems that PropertyChanged is not working with ExpandoObject and data binding.

It workds as intended in WPF, but not in a Store App. See comparison: https://sites.google.com/site/moramatte/ExpandoComparison.zip?attredirects=0&d=1

user958578
  • 311
  • 3
  • 5
  • PropertyChanged works in ExpandoObject, see simple sample [here](http://pastebin.com/pyKCiGG4). The problem must be something else. Please provide a small but complete example that reproduces this behavior. – Daniel Hilgarth Nov 29 '12 at 07:25
  • 5
    It works as intended in WPF, but not in a Store App. Check out my simple comparison: https://sites.google.com/site/moramatte/ExpandoComparison.zip?attredirects=0&d=1 – user958578 Nov 29 '12 at 09:35
  • 2
    I filed a Connect bug: https://connect.microsoft.com/VisualStudio/feedback/details/836252/databinding-in-windows-store-apps-to-an-expandoobject-change-notification-not-working – Luke Puplett Mar 18 '14 at 17:48

2 Answers2

1

They didn't add a default mechanism for binding to dynamic objects and instead added a new interface ICustomTypeProvider. And that interface wasn't added to an ExpandoObject either, but with expando you should be able to use the indexer binding since it is an IDictionary<string, object> that implements INotifyPropertyChanged.

<TextBlock Text="{Binding [Foo]}"/>
Roster Neo
  • 11
  • 1
0

Going over this again I conclude that binding is not working for attribute updates (the ones handled with INotifyPropertyChanged) for WinRT/Win10 (Build 10240) when using ExpandoObjects.

INotifyCollectionChanged works - so lists of ExpandoObjects are updated as they change - but their properties are not correctly hooked up by Binding.

One workaround is to create a value object and keep this in each expandoobjectproperty:

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"));
        }
      }
    }
  }
}

I can then successfully bind and get updates from properties in expandoobjects like this:

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

I assign new properties like this:

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

I update properties like this:

var listitem = (thelist[0] as dynamic);
  listitem.Attribute1.Value = "UPDATE";
Hans Karlsen
  • 2,275
  • 1
  • 15
  • 15