Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UI does not update with list of ExpandoObject

I have implemented the dynamic dataGrid by following this link.

I am using Converter to bind the values from ExpandoObject. The columns shows values like total units for schools.

Item      ItemCount DefaultSchool School1  School2 School3

X-Item    200       100           50       50      0

Schools can be added dynamically at any time. Now if I add the School4 with 40 units, I want to deduct the same from default school (DefaultSchool = 60, School4 = 40).

I can make this calculations in the converter and the ItemsSource also shows the updated value but it does not reflect on the UI.

What I use the TextBox's LostFocus event with MyDataGrid.Items.Refresh, it does update the UI, but every time on lost focus, the UI will also flickers, just like a refreshing web page).

I just need to update the current row. As I am using ExpandoObject, I can't use the INotifyPropertyChanged (I believe?), so what should be the best approach in this scenario?

So how should I update the UI?

like image 247
Learner Avatar asked Nov 03 '22 13:11

Learner


1 Answers

I believe this isn't a problem with ExpandoObject not implementing INotifyPropertyChanged (because it does).

What I'm thinking is that your problem is the combination of INotifyCollectionChanged and using a converter. What happens is that converters are called when the property changes, but they aren't called when the collection changes. This will cause the UI not to update when an item is added or removed from the bound collection.

You can have a look at these questions for more information about this problem:

  • How do I update an IValueConverter on CollectionChanged?
  • Why is Converter not called when Collection changes?

You could see if that's really your issue by setting a breakpoint in your converter and see if it's being called when you add the new item. If that's indeed the issue, you could either try to work your way around this without using a converter, or use a MultiValueConverter that will also receive the Count property (which will only act as a trigger), like so:

<DataGrid>
    <DataGrid.ItemsSource>
        <MultiBinding Converter="{local:MyConverter}">
            <Binding Path="Items" />
            <Binding Path="Items.Count" />
        </MultiBinding>
    </DataGrid.ItemsSource>
</DataGrid>
public class MyConverter : MarkupExtension, IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // Your converter logic which will use values[0] (the bound collection).

        // Ignore anything else in the values[] array.
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}
like image 156
Adi Lester Avatar answered Nov 15 '22 06:11

Adi Lester