0

I have a listview in my WPF application and the first column is a Checkbox. This checkbox is bound to the IsSelected property of my model and the event propogation happens correctly.

I also have a Checkbox in the same column's header and want to implement a 'Select All' feature where it checks all the listview items.

I can attach to the process and see that the data is changing when I go and programatically change the data in the model, but it does not reflect in the UI. I have INotifyPropertyChanged implemented as well.

Can someone explain what I am doing wrong here..

The relevant code portions are mentioned below..

Xml:

<ListView Height="470" ItemsSource="{Binding Path=Songs,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" IsSynchronizedWithCurrentItem="True"
                      x:Name="yourSongListView" GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler"

                      ItemContainerStyle="{StaticResource itemStyle}" AlternationCount="2">
                <ListView.View>
                    <GridView ColumnHeaderContainerStyle="{StaticResource CustomHeaderStyle}" >
                        <GridView.Columns>
                            <GridViewColumn HeaderTemplate="{StaticResource checkboxHeaderTemplate}" 
                                            CellTemplate="{StaticResource CheckBoxCell}" Width="30">

                            </GridViewColumn>
                            <GridViewColumn CellTemplate="{StaticResource TitleTemplate}" Width="450">
                                <GridViewColumnHeader Content="TITLE" Tag="Title" />
                            </GridViewColumn>
                        </GridView.Columns>
                    </GridView>
                </ListView.View>
            </ListView>


<DataTemplate x:Key="checkboxHeaderTemplate">
            <CheckBox Checked="CheckBox_Checked">
                <CheckBox.Template>
                    <ControlTemplate TargetType="CheckBox">
                        <Image Name="TickImage" Source="Images\track-list-select.png" Width="18" Height="18" />
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsChecked" Value="True">
                                <Setter TargetName="TickImage" Property="Source" Value="Images\track-list-select-active.png" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </CheckBox.Template>
            </CheckBox>
        </DataTemplate>


 <DataTemplate x:Key="CheckBoxCell">
            <CheckBox  IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" >
                <CheckBox.Template>
                    <ControlTemplate TargetType="CheckBox">
                        <Image Name="TickImage" Source="Images\track-list-select.png" Width="18" Height="18" />
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsChecked" Value="True">
                                <Setter TargetName="TickImage" Property="Source" Value="Images\track-list-select-active.png" />
                             </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </CheckBox.Template>
            </CheckBox>
        </DataTemplate>

Code :

 private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            CheckBox c = sender as CheckBox;
            if (c.IsChecked.HasValue)
            {
                Model.ToggleAllSelection(c.IsChecked.Value);
            }
            else
            {
                Model.ToggleAllSelection(false);
            }
        }


 public void ToggleAllSelection(bool newState)
            {
                foreach (var item in Songs)
                {
                    item.IsSelected = newState;
                    InvokePropertyChanged("IsSelected");
                }

                InvokePropertyChanged("Songs");
            }

Songs is a ObservableCollection

1 Answer 1

1

If you wish to fire property changed on a property you will need to fire the event in the class which owns the property.

In your example you are not firing the event inside the class Song.

This is how you should fire the event properly:

class Song
{
  prop IsSelected
  {
    get { return this.selected; }
    set { this.selected = value; PropertyChanged("IsSelected"); }
  }
}

OLD: Could you show us what is InvokePropertyChanged doing?

Where does the method ToggleAllSelection come from?

Sorry I apply this as answer. I cannot post comments yet.

Sign up to request clarification or add additional context in comments.

5 Comments

InvokePropertyChanged("Songs"); is just the implementation of INotifyPropertyChanged interface.. and ToggleAllSelection() changes the IsSelected property of my model..
What is the name of the class containing InvokePropertyChanged? What is the name of the class containing ToggleAllSelection? Are those two different classes?
No they are the same class.. the class implements INotifyPropertyChanged
I edited my answer. You are not firing the propertychanged event properly.
This worked.. I understand now.. the objects inside the collection are not dependency objects and so do not fire off change notification events.. Thanks..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.