0

I'm beginner and I tried to search everywhere for a similar problem, this question has been asked many times but I couldn't find any solution.

I implemented INotifyPropertyChanged like this (it is working correctly):

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            MessageBox.Show("property changed");
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

My observablecollection look like this :

    ObservableCollection<bool>  Test = new ObservableCollection<bool>(new[] { false, false, false, false, false, false });

    private ObservableCollection<bool> _Collection;
    public ObservableCollection<bool> Collection
    {
        get { return _Collection = Test; }
        set { _Collection = value; OnPropertyChanged("Collection"); }
    }

This collection is bound to togglebutton's property contained in usercontrols :

VidFlipX="{Binding DataContext.Collection[1], ElementName=cmix, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

Data changed correctly while using them but if I set the collection in an other way, OnPropertyChanged is not firing and so my togglebuttons are not updated.

Can't find out why...

lecloneur
  • 424
  • 5
  • 20
  • How are you using `Collection` in XAML? – Mike May 06 '16 at 09:08
  • hi mike, I edited my post. Thanks – lecloneur May 06 '16 at 09:12
  • Binding DataContext.Collection[1] is you problem you are bound to the first element of the collection which is bool. – Radin Gospodinov May 06 '16 at 09:14
  • Yes because this VidFlipX properties belongs to a usercontrol used 6 times. Each of them are using the same observablecollection. The XAML posted above is from second usercontrol. – lecloneur May 06 '16 at 09:15
  • PropertyChanged is not fired when you edit an item in you collection, if you add, remove or replace items ObservablleCollection fires CollectionChanged event. If you want your binding to work create a new class VidFlipX with a boolean property Flip{get;set{fire property changed here}}. Fill your collection with instances of this class. Then bind like this: "DataContext.Collection[1].Flip". – Radin Gospodinov May 06 '16 at 09:19
  • 2
    In `get { return _Collection = Test; }` you are **always** returning `Test`. The property setter (and therefore also the INotifyPropertyChanged implementation) is useless. – Clemens May 06 '16 at 09:21
  • Hi Clemens, I understand. But still, Test is being modified when changing the VidFlipX property. If my actual way of declaring the collection is wrong, what would you recommend ? thanks – lecloneur May 06 '16 at 09:24
  • It's not clear what your problem is. Where are you setting `Collection`? – Charles Mager May 06 '16 at 09:25
  • `get { return _Collection; }` of course! – Clemens May 06 '16 at 09:26
  • @Clemens that's `_Collection`, not `Collection`... – Charles Mager May 06 '16 at 09:26
  • @CharlesMager What's your point? `_Collection` is the backing field of the `Collection` property, of which I showed how to write the getter. – Clemens May 06 '16 at 09:28
  • My point is no property change will be fired unless `Collection` is set, as the setter fires the event. Setting the backing field is not going to raise the event. I'm asking where `Collection` is set, which would give the expectation that the event would be raised, which is what the question implies should happen. – Charles Mager May 06 '16 at 09:29
  • "no property change will be fired unless Collection is set". Obviously, but that's another point, unrelated to the broken getter. Of course, the property setter has to be called, but then the getter should return the value that was set before. – Clemens May 06 '16 at 09:31
  • @Clemens yes, but i wasn't commenting on a broken getter - you were ;). I was simply asking why there is an expectation the event is fired when no code presented shows the setter being called. – Charles Mager May 06 '16 at 09:33
  • The setter is called when loading data from JSON file. – lecloneur May 06 '16 at 09:34
  • @CharlesMager Then why you addressed me at all in "@Clemens that's _Collection, not Collection". Doesn't make sense... – Clemens May 06 '16 at 09:35
  • @Clemens because you appeared to be replying to my comment where I'd asked where `Collection` was set.... and now I re-read it, you probably weren't! Apologies. Maybe where the comments aren't in order, including the `@` is a good idea. – Charles Mager May 06 '16 at 09:38

2 Answers2

2

With changing a item of your collection, you are not changing your collection. So you are not calling the setter of your collection. To update the item on your Ui, your items in your collection have to implement the INotifyPropertyChanged like described here.

A solution could be like this:

ObservableCollection<ClassA> Test { get; set; }

With your class:

class ClassA : INotifyPropertyChanged
{
    private bool _isEnabled;
    public bool IsEnabled
    {
        get { return _isEnabled; }
        set
        {
            if (value != _isEnabled)
            {
                _isEnabled = value;
                OnPropertyChanged("IsEnabled");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
Community
  • 1
  • 1
Fruchtzwerg
  • 10,999
  • 12
  • 40
  • 49
0

You must not call

return _Collection = Test;

in the getter of your Collection property, because this renders the setter (and hence the whole INotifyPropertyChanged implementation) useless. The value passed to the setter is never used anywhere.

When you need to initialize your property with a predefined collection, you could do it like this:

private ObservableCollection<bool> _Collection
    = new ObservableCollection<bool>(new[] { false, false, false, false, false, false });

public ObservableCollection<bool> Collection
{
    get { return _Collection; }
    set { _Collection = value; OnPropertyChanged("Collection"); }
}
Clemens
  • 123,504
  • 12
  • 155
  • 268
  • I just tried. Items in the ObservableCollection are modified but OnPropertyChanged is not firing. – lecloneur May 06 '16 at 09:43
  • `OnPropertyChanged` in the `Collection` setter is only called when the setter is called, i.e. when an assignment is made on the property (like `Collection = ...`). When items are added or removed, the ObservableCollection fires a CollectionChanged event. When collection elements are modified, they should fire their own PropertyChanged event, as shown in the answer given by Fruchtzwerg. – Clemens May 06 '16 at 09:47
  • 1
    @lecloneur see @Fruchtzwerg's [answer](http://stackoverflow.com/a/37068533/1320845) I think you may have misunderstood how `INotifyPropertyChanged` interacts with `ObservableCollection`. – Charles Mager May 06 '16 at 09:47