I am new to WPF. I found a few examples and put together a tree-view example in C# WPF Mvvm. I got the children's checkboxes checked or unchecked based on parent selection. I am not sure how to access the parent binding or property to check or uncheck it based on children. If all children are selected, I expect parents to be checked, and if even one child is unchecked, I want parents to be unchecked. How do I achieve this using the MVVM viewmodel? Any suggestions would be greatly appreciated.
Xaml View
<Window x:Class="WpfApp1.MainWindow"
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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:MainViewModel></local:MainViewModel>
</Window.DataContext>
<Window.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:CheckableItem}" ItemsSource="{Binding
Children, Mode=TwoWay}">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeView}},
Path=DataContext.CheckBoxCommand}" CommandParameter="{Binding}"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</HierarchicalDataTemplate>
</Window.Resources>
<StackPanel>
<Label Content="Miscellaneous Imports" HorizontalAlignment="Center" />
<ScrollViewer>
<TreeView ItemsSource="{Binding MiscellaneousImports, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="10" Height="450"/>
</ScrollViewer>
</StackPanel>
ViewModel
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public ICommand CheckBoxCommand { get; set; }
public MainViewModel()
{
LoadCheckableItems();
CheckBoxCommand = new DelegateCommand<CheckableItem>(OnCheckBoxChecked);
}
private void OnCheckBoxChecked(CheckableItem item)
{
throw new NotImplementedException();
}
private ObservableCollection<CheckableItem> miscellaneousImports;
public ObservableCollection<CheckableItem> MiscellaneousImports
{
get { return miscellaneousImports; }
set
{
miscellaneousImports = value;
OnPropertyChanged("MiscellaneousImports");
}
}
private void LoadCheckableItems()
{
List<CheckableItem> lstItems = new List<CheckableItem>();
CheckableItem item = new CheckableItem
{ Name = "Coffee", Children = new ObservableCollection<CheckableItem>() { new CheckableItem { Name="Medium" }, new CheckableItem {Name="Dark" } } };
lstItems.Add(item);
MiscellaneousImports = new ObservableCollection<CheckableItem> ( lstItems );
}
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Checkbox collection class
public class CheckableItem:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged("Name");
}
}
public ObservableCollection<CheckableItem> Children { get; set; }
private bool _isChecked;
public bool IsChecked
{
get { return _isChecked; }
set
{
_isChecked = value;
OnPropertyChanged("IsChecked");
if (Children != null)
{
foreach (CheckableItem child in Children)
{
child.IsChecked = IsChecked;
}
OnPropertyChanged(nameof(Children));
}
}
}
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Aucun commentaire:
Enregistrer un commentaire