wpflistviewdatatemplateitemtemplate

How to set selected item(s) in a listView from a collection of an object


I'm setting up a WPF control using a ListView which displays a list of items from an observable collection of class objects (here - AllSettingsCollection<MySettings>) present in my Model. Where MySettings is a class which contains some hardware settings.

I am able to set the ItemSource of the list view as

ItemsSource="{Binding  Model.AllSettingsCollection}"

and display the name in each row using a DataTemplate (code below) but i am not able to set the selected property of each row based on the IsSelected property.

Suppose the class (MySettings) is as below

public class MySettings
{
  public string Name{get; private set;}
  public string IsSelected{get; private set;}
}

and objects of this class are in the collection AllSettingsCollection which is an ObservableCollection<MySettings>

Now if i setup my ListView as below

<ListView
      Grid.Row="0"
      HorizontalContentAlignment="Stretch"
      ItemsSource="{Binding Model.AllSettingsCollection}"
      SelectionMode="Multiple"
      Style="{StaticResource ListViewStyle}">
      <ListView.View>
        <GridView AllowsColumnReorder="False">
          <GridViewColumn
            DisplayMemberBinding="{Binding Name}"
            Header="Settings:" >
            <GridViewColumn.CellTemplate>
              <DataTemplate>
                <TextBlock HorizontalAlignment="Stretch" Text="{Binding}" />
              </DataTemplate>
            </GridViewColumn.CellTemplate>
          </GridViewColumn>
          <GridView.ColumnHeaderContainerStyle>
            <Style BasedOn="{StaticResource NonResizableGridViewColumnHeaderStyle}" TargetType="{x:Type GridViewColumnHeader}">
            </Style>
          </GridView.ColumnHeaderContainerStyle>
        </GridView>
      </ListView.View>
      <ListView.ItemContainerStyle>
        <Style BasedOn="{StaticResource ListViewItemStyle}" TargetType="{x:Type ListViewItem}">
        </Style>
      </ListView.ItemContainerStyle>
    </ListView>

since my ListView.ItemsSource is the Model.AllSettingsCollection, i am able to generate each row with a name. but i am not able to find where i can set the property IsSelected of each row.

Where can i set the isSelected property of each row if the ListView, so ideally i could have have a statement like

<Setter Property="IsSelected" Value="{Binding IsSelected}"/>

which takes each row and marks it as selected or not based on the IsSelected property of the object in the collection.

Note: I would also like to have each rows isSelected have a changed event, which responds to if the user changes which set of items are selected, but this is something i will look at later.


Solution

  • Move the Setter into the ItemContainerStyle:

    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
        </Style>
    </ListView.ItemContainerStyle>
    

    And make sure the source property is of type bool and has a public setter that fires a change notification:

    public class MySettings : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        public string Name { get; private set; }
    
        private bool isSelected;
        public bool IsSelected
        {
           get { return isSelected; }
           set
           {
               isSelected = value;
               PropertyChanged?.Invoke(this,
                   new PropertyChangedEventArgs(nameof(IsSelected)));
           }
        }
    }