C# wpf Как сделать группировку с checkbox?
У меня есть ListView с группировкой по определенному ключу. У меня есть checkbox's у родителя и у элементов. Мне нужно, чтобы по нажатию на checkbox родителя, все элементы поменяли свое состояние

У меня есть проблема при создании groupstyle для listview. Там можно привязаться через RelativeSource только к одному свойству
<Window x:Class="FillResources.DialogWindows.AddLanguagesWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FillResources.DialogWindows"
xmlns:vm="clr-namespace:FillResources.ViewModels"
mc:Ignorable="d"
Title="AddLanguagesWindow" Height="300" Width="400">
<Window.DataContext>
<vm:AddLanguagesWindowViewModels />
</Window.DataContext>
<Grid>
<ListView Name="lvLanguages" ItemsSource="{Binding Languages}">
<ListView.View>
<GridView>
<GridViewColumn Header="" Width="40" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Name" Width="Auto" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Code" Width="Auto" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Code}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Height" Value="30" />
</Style>
</ListView.ItemContainerStyle>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True" >
<Expander.Header>
<StackPanel Orientation="Horizontal">
<CheckBox VerticalAlignment="Center" Margin="5" IsChecked="{Binding Path=DataContext.IsAllSelectedPopular, RelativeSource={RelativeSource AncestorType=Window}}" />
<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="Gray" FontSize="22" VerticalAlignment="Bottom" />
<TextBlock Text="{Binding ItemCount}" FontSize="22" Foreground="Green" FontWeight="Bold" FontStyle="Italic" Margin="10,0,0,0" VerticalAlignment="Bottom" />
<TextBlock Text=" item(s)" FontSize="22" Foreground="Silver" FontStyle="Italic" VerticalAlignment="Bottom" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</Grid>
</Window>
Ответы (1 шт):
При создании WPF-приложений удобно использовать реактивные расширения и их реализацию под .NET - ReactiveUI. С помощью реактивных расширений вы можете легко управлять зависимостями между частями данных и их быстрой конвертацией. Крайне советую.
Для вашего случая сделал следующий простой пример. В конструкторе я подписываюсь(this.WhenAnyValue...) на изменение RootElement(ваш родительский элемент списка) и при возникновении этого события вызываю метод ChangeAllValues. При этом для каждого элемента вызывается INotifyPropertChanged.
public class MainWindowViewModel : ReactiveObject
{
public SourceList<bool> Elements { get; set; }
[Reactive]
public bool RootElement { get; set; }
public MainWindowViewModel()
{
Elements = new SourceList<bool>();
Elements.Add(true);
Elements.Add(false);
this.WhenAnyValue(x => x.RootElement)
.Subscribe(rootValue => ChangeAllValues(rootValue));
}
private void ChangeAllValues(bool rootValue)
{
for (int i = 0; i < Elements.Items.Count(); i++)
{
Elements.ReplaceAt(i, rootValue);
}
}
}
Еще большое про реактивные расширения: