So I have like 5 CheckBoxes and want to get the different State of Check on every CheckBox when I click on one Button. So when my CheckBoxes is unchecked and I click on the Button then is the CheckBoxes checked and when CheckBoxes is Checked and I click on the Button it is unchecked.
The Problem I got, is that I only want to get this work with XAML. With Code behind thats not the Problem, but I want to get this to work with only Bindings.
CodePudding user response:
So, as you said:
I want to get this to work with only Bindings
You have Window
with few CheckBox
es on it and Button
, which switches check state. Set up CheckBox
es with Bindings to some AllChecked
property (we will create it at code-behind):
XAML:
<Window x:Class="WpfApp.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:WpfApp"
mc:Ignorable="d"
Title="MainWindow"
Height="150"
Width="400"
Name="mainWindow"
KeyDown="OnKeyDown">
<Window.Resources>
<local:BooleanToStringConverter x:Key="BoolToStringConverter"/>
</Window.Resources>
<Grid>
<StackPanel x:Name="checkBoxPanel"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="10,10,0,0">
<!-- Binding CheckBoxes and disabling them -->
<CheckBox IsChecked="{Binding ElementName=mainWindow,
Path=AllChecked,
UpdateSourceTrigger=PropertyChanged}"
Content="CheckBox1"
IsEnabled="False"/>
<CheckBox IsChecked="{Binding ElementName=mainWindow,
Path=AllChecked,
UpdateSourceTrigger=PropertyChanged}"
Content="CheckBox2"
IsEnabled="False"/>
<!-- Same 3 other CheckBoxes -->
</StackPanel>
<!-- Button also binded to same property. -->
<!-- With Converter its Text change between "Check All" and "Uncheck All" -->
<Button x:Name="btnCheckUncheckAll"
Content="{Binding ElementName=mainWindow,
Path=AllChecked,
UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource BoolToStringConverter},
ConverterParameter=btnCheckUncheckAll}"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Margin="0,10,0,0"
Width="100"
Height="32"
Click="ButtonCheckUncheckAll_Click"/>
</Grid>
</Window>
All CheckBox
es disabled in example due to your comment "...I dont want to Click an CheckBox". As @Shrimperator noticed, checking one will cause checking of all CheckBox
es, because they binded to same source (it's another readon why they disabled). BooleanToStringConverter
uses AllChecked
property value to set "Check All" or "Uncheck All" button text (see its code at code-behind part). I pass button x:Name
as parameter to converter, to be able use converter for other different buttons in future, not only for this one.
Window look:
Code-behind:
using System;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
namespace WpfApp
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
private bool allChecked;
// Single property each CheckBox binded to
public bool AllChecked
{
get => allChecked;
set
{
allChecked = value;
// Notify binded controls that we changed value
OnPropertyChanged(nameof(AllChecked));
}
}
// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyName = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
// Constructor
public MainWindow() => InitializeComponent();
// If button control clicked - check state on each CheckBox will change
private void ButtonCheckUncheckAll_Click(object sender, RoutedEventArgs e) =>
SwitchCheckState();
private void OnKeyDown(object sender, KeyEventArgs e)
{
// If C button pressed - check state on each CheckBox will change
if (e.Key == Key.C)
SwitchCheckState();
}
// Simply switch between True and False
private void SwitchCheckState() =>
AllChecked = !AllChecked;
}
public class BooleanToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (parameter is string buttonName && buttonName == "btnCheckUncheckAll")
return (bool)value == true ? "Uncheck all" : "Check all";
return string.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
string.Empty;
}
}
So we have simple SwitchCheckState
method to change AllChecked
property between True
and False
. It is called by Button click (ButtonCheckUncheckAll_Click
handler) or by C(heck) key press (OnKeyDown
handler on whole Window). We change just AllChecked
property value in any way we wish, when INotifyPropertyChanged
and Bindings do other magic somewhere behind.
It is simplified example, without ViewModels and DataContexting. Post a comment if you have other questions, improvement suggestions or need some another explanations.