I have a WPF application that utilizes a ListView with a bound source. Each ListViewItem is a custom View with controls bound to properties of the underlying data. I'm using the Extended SelectionMode and would like a way for all selected items to have the properties modified when one item is interacted with while multiple are selected.
Example Usage: * Select all the items in my list. * Click on "Property 1" for one of the items. * Have all item's Property 1 flag set to true.
Is there a way to accomplish this? I can think of a few hacks but nothing that feels clean.
Example Code:
MainWindow.xaml
<Window.DataContext>
<ViewModels:MainWindowViewModel/>
</Window.DataContext>
<ListView x:Name="MyList" Height="auto" Width="auto" Grid.Row="1" ItemsSource="{Binding ListSource}">
<ListView.ItemTemplate>
<DataTemplate x:Name="ItemTemplate" DataType="ViewModels:FlagCollectionViewModel">
<Views:FlagCollectionView />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
FlagCollectionViewModel.xaml:
<UserControl x:Class="WpfApp2.Views.FlagCollectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp2.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
BorderBrush="Black"
BorderThickness="1">
<UserControl.Resources>
<Style TargetType="CheckBox">
<Setter Property="Width" Value="auto"/>
<Setter Property="Height" Value="auto"/>
<Setter Property="Margin" Value="3"/>
</Style>
</UserControl.Resources>
<Grid Width="auto" Height="auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Content="{Binding Name}"/>
<CheckBox Grid.Row="1" Grid.Column="0" IsChecked="{Binding Flag1}">Property 1</CheckBox>
<CheckBox Grid.Row="1" Grid.Column="1" IsChecked="{Binding Flag2}">Property 2</CheckBox>
<CheckBox Grid.Row="1" Grid.Column="2" IsChecked="{Binding Flag3}">Property 3</CheckBox>
</Grid>
</UserControl>
MainWindowViewModel:
public class MainWindowViewModel
{
public MainWindowViewModel()
{
_ListSource = new ObservableCollection<FlagCollectionViewModel>();
_ListSource.Add(new FlagCollectionViewModel("Instance 1"));
_ListSource.Add(new FlagCollectionViewModel("Instance 2"));
_ListSource.Add(new FlagCollectionViewModel("Instance 3"));
_ListSource.Add(new FlagCollectionViewModel("Instance 4"));
}
private ObservableCollection<FlagCollectionViewModel> _ListSource = null;
public ObservableCollection<FlagCollectionViewModel> ListSource => _ListSource;
}
FlagCollectionViewModel.cs
public class FlagCollectionViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public FlagCollectionViewModel(string NameIn)
{
_Name = NameIn;
}
private string _Name;
public string Name => _Name;
private bool _Flag1, _Flag2, _Flag3;
public bool Flag1
{
get => _Flag1;
set => SetFlag(ref _Flag1, value, nameof(Flag1));
}
public bool Flag2
{
get => _Flag2;
set => SetFlag(ref _Flag2, value, nameof(Flag2));
}
public bool Flag3
{
get => _Flag3;
set => SetFlag(ref _Flag2, value, nameof(Flag3));
}
private void SetFlag(ref bool Target, bool Value, string PropertyName)
{
Target = Value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
System.Diagnostics.Debug.Print(Name + ": " + Flag1 + ", " + Flag2 + ", " + Flag3);
}
}