UpdateSourceTrigger PropertyChanged on IsChecked Isn't Firing on ItemsSource of ListBox of Checkboxes
Asked Answered
K

1

2

I have a listbox in which the item source contains a List(of T) that has a SelectedFlag boolean property. My viewmodel is set as the DataContext of my user control and everything is working as expected except I can't get the property change even when a check box is changed.

Here is my xaml ListBox

<ListBox x:Name="lstRole" ItemsSource="{Binding Path=FAccountFunctions, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="Id">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <CheckBox IsChecked="{Binding Path=SelectedFlag, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" />
                            <TextBlock Text="{Binding Path=FunctionDesc}" VerticalAlignment="Center" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

I need to call my Filter() function after a check box is checked and I normally would set the UpdateSourcTrigger=PropertyChanged to make this work.

Public Property FAccountFunctions As List(Of FunctionType)
        Get
            Return _faccountFunctions
        End Get
        Set(ByVal value As List(Of FunctionType))
            _faccountFunctions = value
            Filter()
        End Set
    End Property

The PropertyChangedEvent is getting raised on the 'SelectedFlag' property in the FAccountFunctions collection. How can I raise an event on the items source when one of the properties SelectedFlag changes?

Changed my FAccountFunctions property to an ObservableCollection...no luck.

Kidnap answered 18/4, 2011 at 17:46 Comment(0)
A
3

You'll need to make your Collection's CollectionChanged event fire when your Item's PropertyChanged event fires.

Something like:

MyCollection.CollectionChanged += MyCollectionChanged;

...

void MyCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.NewItems != null)
    {
        foreach (object item in e.NewItems)
        {
            if (item is MyItem)
                ((MyItem)item).PropertyChanged += MyItem_PropertyChanged;
        }
    }

    if (e.OldItems != null)
    {
        foreach (object item in e.OldItems)
        {
            if (item is MyItem)
                ((MyItem)item).PropertyChanged -= MyItem_PropertyChanged;
        }
    }
}

...

void MyItem_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    OnPropertyChanged("MyCollection");
}
Ane answered 18/4, 2011 at 20:7 Comment(4)
Thanks for your answer! I implemented your solution but the MyCollectionChanged isn't getting called. I put AddHandler FAccountFunctions.CollectionChanged, AddressOf MyCollectionChanged in the constructor of my ViewModel before the collection gets loaded. Because of this MyItem_PropertyChanged never gets called. I might have to utilize Checked event in my code behind :(Kidnap
@Kidnap Are you using an ObservableCollection for MyCollection? And are you Creating the ObservableCollection BEFORE attaching the CollectionChanged event? If you are creating it afterwards than the new object won't have the Changed event attached.Ane
I am currently grappling with the problem your answer above says to give a solution. My implementation more or less is parallel to yours above, but when I call "OnPropertyChanged("MyCollection")" in the item-changed-event-handler nothing "MyCollection" related happens, especially no update in data bound target dependency properties in an other class. So as a last resort I appended an element and deleted it immediately - this gave me a reaction in the bound dependency property, but it is of course ugly. Can you shed some light on what is going on here?Archaeopteryx
I found a solution now: Instead of calling "OnPropertyChanged("MyCollection")" I did "MyCollection[0] = MyCollection[0]". Strangely(?) this worked!Archaeopteryx

© 2022 - 2024 — McMap. All rights reserved.