Ksice
Ksice

Reputation: 3327

ListBox bind to ObservableCollection is not updated with collection

I have next model:

public class MyModel
{
    public ObservableCollection<MyObject> MyList {get; set;}
}

public class MyObject
{
   MyObservableDictionary MyDictionary {get; set;}
}

public class  MyObservableDictionary : ObservableCollection<EnymValue>
{
}

public class EnymValue : INotifyPropertyChanged
{
  private MyEnum key;
    private string value;

    public MyEnum Key
    {
        get
        {
            return this.key;
        }
        set
        {
            this.key = value;
            NotifyPropertyChanged("Key");
        }
    }
    public string Value
    {
        get
        {
            return this.value;
        }
        set
        {
            this.value = value;
            NotifyPropertyChanged("Value");
        }
    }

    public LanguageValue(MyEnum key, string value)
    {
        this.Key = key;
        this.Value = value;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName]string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

public enum MyEnum
{
}

And on View I have a ListBox:

<ListBox x:Name="MyList" SelectionMode="Single" ItemsSource="{Binding Path=MyList, Mode=OneWay}">
     <ListBox.ItemTemplate>
        <DataTemplate>
             <TextBlock Text="{Binding Path=MyDictionary, Mode=OneWay, Converter={StaticResource myEnumToTextConverter}}" />
         </DataTemplate>
      </ListBox.ItemTemplate>
</ListBox>

(myEnumToTextConverter converter is just selects first element from collection and return it's value, or some specified constant if collection is null or empty)

I want my Model's list box to be updated on view, when any EnymValue values are changed. Is it possible somehow to implement this?

Currently the view is not updated when Value changed. I've tried to inherit EnymValue from INotifyPropertyChanged, but this didn't helped. Looks like PropertyChanged == null on EnymValue.NotifyPropertyChanged when property updated.

Upvotes: 0

Views: 675

Answers (2)

AnjumSKhan
AnjumSKhan

Reputation: 9827

Your MyDictionary should force a refresh. Easiest way is to re-assign its old value, and implement INPC in MyObject like below :

public class MyObject: INotifyPropertyChanged
    {
        MyObservableDictionary _myDictionary;
        public MyObservableDictionary MyDictionary {
            get
            {
                return _myDictionary;
            }
            set
            {
                _myDictionary = value;
                OnPropertyChanged("MyDictionary");
            }
        }

        public MyObject()
        {
            MyDictionary = new MyObservableDictionary();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string prop)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }
    }

Sample code to change Value :

private void Button_Click(object sender, RoutedEventArgs e)
{
    // vm is ViewModel instance, vm is DataContext set for Window

    var old = vm.MyList[0].MyDictionary;
    vm.MyList[0].MyDictionary[0].Value = "aaaa";
    vm.MyList[0].MyDictionary = old;
}

I tested this, and it displays changed value as "aaaa".

Upvotes: 0

3615
3615

Reputation: 3877

ObservableCollection is able to notify UI about changes when collection itself is changed(elemends are added or deleted). But ObservableCollection is not aware of changes that are happening when you modify one of it's items. To solve the problem you may subscribe to CollectionChange event of observable collection, and when new item is added, subscribe to new items's PropertyChanged. When PropertyChanged event is raised, you can trigger notification on your list OnPropertyChanged(()=>MyItems); You should be careful implementing this solution and remember to unsubscribe from the event's to avoid memory leaks.

An example of what I mean you can see in this answer.

Upvotes: 2

Related Questions