Home > Blockchain >  How can I check or uncheck every CheckBox with one Click on one Button and only with XAML?
How can I check or uncheck every CheckBox with one Click on one Button and only with XAML?

Time:11-10

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 CheckBoxes on it and Button, which switches check state. Set up CheckBoxes 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 CheckBoxes disabled in example due to your comment "...I dont want to Click an CheckBox". As @Shrimperator noticed, checking one will cause checking of all CheckBoxes, 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:

enter image description here

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.

  • Related