-1

I'm working on a C# WPF project and I'm searching for a trick to add Uncheck and Check events to the datagridCheckboxColumn, I have already found many solutions but I'm haven't got what I need exactly.

My object is to colorize every checked row with Gray and to colorize every unchecked row by the user with white ( the default color of the datagrid).

The event of the checked row worked perfectly and the row was colored when I checked the datagridCheckboxColumn.

I'm searching for a solution for the unchecked event.

XAML Code

<DataGridCheckBoxColumn Header="Choose" x:Name="choose">
                    <DataGridCheckBoxColumn.CellStyle>
                        <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
                            <EventSetter Event="CheckBox.Checked" Handler="OnChecked"/>
                           
                        </Style>
                        
                    </DataGridCheckBoxColumn.CellStyle>
                </DataGridCheckBoxColumn>  

C# Code


 private void OnChecked(object sender, RoutedEventArgs e)
        {
            for (int i = 0; i < datagridView.Items.Count; i++)
            {
                DataGridRow row = (DataGridRow)datagridView.ItemContainerGenerator.ContainerFromIndex(i);
                CheckBox ch = (CheckBox)datagridView.Columns[0].GetCellContent(row);
                bool ischecked = (bool)ch.IsChecked;

                if (ischecked)
                {
                    row.Background = Brushes.Gray;

                }
                
            }
        }

OhBeWise
  • 5,350
  • 3
  • 32
  • 60
abdou_dev
  • 805
  • 1
  • 10
  • 28

2 Answers2

0

You can use DataGrid.RowStyle property and DataTriggers:

XAML:

<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">
<Grid>

    <DataGrid ItemsSource="{Binding Entries}">
        <DataGrid.RowStyle>
            <Style TargetType="{x:Type DataGridRow}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsChecked}"
                                 Value="True">
                        <Setter Property="Background"
                                Value="Gray" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </DataGrid.RowStyle>
    </DataGrid>
</Grid>

Code behind:

using System.Windows;

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainViewModel();
        }
    }
}

MainViewModel:

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace WpfApp1
{
    public class MainViewModel : INotifyPropertyChanged
    {

        public ObservableCollection<Entry> Entries
        {
            get => entries ?? (entries = new ObservableCollection<Entry>(CreateEntries()));
        }
        ObservableCollection<Entry> entries;

        private List<Entry> CreateEntries()
        {
            return new List<Entry>
            {
                new Entry { Name = "Andy", IsChecked = false },
                new Entry { Name = "Coolman", IsChecked = true },
                new Entry { Name = "Bono", IsChecked = false }
            };
        }

        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }

    public class Entry : INotifyPropertyChanged
    {

        public bool IsChecked
        {
            get { return isChecked; }
            set
            {
                if (isChecked == value) return;
                isChecked = value;
                OnPropertyChanged();
            }
        }
        bool isChecked;


        public string Name
        {
            get { return name; }
            set
            {
                if (name == value) return;
                name = value;
                OnPropertyChanged();
            }
        }
        string name;

        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
}
Paweł Piorun
  • 99
  • 1
  • 3
  • Thanks for the reply but I think that your solution is a little bit complicated – abdou_dev Sep 08 '20 at 20:11
  • This is the easiest way in my opinion, if you want to follow MVVM. Optionally, you may want to change the behaviour of DataGrid which will update the background when lost focus on the row. Here is one solution: https://stackoverflow.com/questions/12329208/wpf-datagrid-not-updating-on-propertychanged And I think with your solution check/uncheck will update all rows, not only the current row with the checkbox that you checked/unchecked. I could help you if you'd share your whole solution. – Paweł Piorun Sep 08 '20 at 20:34
  • Sorry the project is private – abdou_dev Sep 09 '20 at 07:53
0

I found this solution and it's very simple :

XAML CODE:


<DataGridCheckBoxColumn Header="Choose" x:Name="choose">
                    <DataGridCheckBoxColumn.CellStyle>
                        <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
                            <EventSetter Event="CheckBox.Checked" Handler="OnChecked"/> 
                            <EventSetter Event="CheckBox.Unchecked" Handler="OnChecked"/> 

                           
                        </Style>
                        
                    </DataGridCheckBoxColumn.CellStyle>
                </DataGridCheckBoxColumn>  

C# CODE



 private void OnChecked(object sender, RoutedEventArgs e)
        {
            for (int i = 0; i < datagridView.Items.Count; i++)
            {
                DataGridRow row = (DataGridRow)datagridView.ItemContainerGenerator.ContainerFromIndex(i);
                CheckBox ch = (CheckBox)datagridView.Columns[0].GetCellContent(row);
                bool ischecked = (bool)ch.IsChecked;

                if (ischecked)
                {
                    row.Background = Brushes.Gray;

                }
                else 
                {
                    row.Background = Burshes.White;
                
            }
        }

abdou_dev
  • 805
  • 1
  • 10
  • 28