简体   繁体   中英

Checkbox in wpf listview header not checking all items

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM