Home > other >  Compare the cell values of the selected checkboxes in DataGridView
Compare the cell values of the selected checkboxes in DataGridView

Time:12-17

I have a DataGridView and Checkbox column attached to it. I would like to achieve something like this, when a few checkboxes are selected, it will compare the cells value of column named Description between those selected row. If the values are not same, a message box will be show up, else the value will be parse into a textbox.

Example

As in example above, a messagebox should be show up when those rows are selected.

This is what i have done so far and i don't know how to continue from here.


private void datagridview1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            foreach (DataGridViewRow r in datagridview1.Rows)
            {
                bool ckboxselected = !Convert.ToBoolean(r.Cells[0].Value);

                if (e.RowIndex >= 0 && e.ColumnIndex == 0)
                {
                    if (ckboxselected)
                    {
                        //compare
                    }
                    else
                    {
                        //another action
                    }
                }
            }
        }

I appreciate you help!

CodePudding user response:

From what you write, I think your code should look like something along the lines of this:

    private void datagridview1_CellClick(object sender, DataGridViewCellEventArgs e)
    {
        string description =null;
        bool differentDescriptionsChecked=false;
        foreach (DataGridViewRow r in datagridview1.Rows)
        {
            bool ckboxselected = Convert.ToBoolean(r.Cells[0].Value);
            if (ckboxselected)
            {
                 string description2 = Convert.ToString(r.Cells[2].Value);
                 if(description==null)
                 {
                      description=description2;
                 }
                 else if(description!=description2)
                 {
                      differentDescriptionsChecked=true;
                      break;
                 }
            }
        }
        if(description==null)
        {
              // show message "no row checked"
        }
        else if(differentDescriptionsChecked)
        {
             // show message "different descriptions checked"
        }
        else
        {
             // do something with "description"
        }
    }

Note I removed the if (e.RowIndex >= 0 && e.ColumnIndex == 0) from your code, it looked superfluous for me (but maybe I am missing something). Also in ckboxselected = !Convert.ToBoolean(r.Cells[0].Value); the "not" operator did not look right (decide by yourself if your original version was correct).

When the requirements become slightly more complicated, I would recommend to approach this in more than step: first, fill some collection like a list, hashset or dictionary with the content from the rows which you are interested in. Then, in a second step evaluate the content to make decisions from it. That could have been done here in this case, too.

CodePudding user response:

Another approach is to load the DataGridView using a class which means when performing assertions there is, in this case a call to commit changes of the DataGridViewCheckBoxColumn.

enter image description here

Sample model/class, where INotifyPropertyChanged notifies clients that a property value has changed.

public class Item : INotifyPropertyChanged
{
    private bool _selected;
    private string _description;



    public bool Selected
    {
        get => _selected;
        set
        {
            _selected = value;
            OnPropertyChanged();
        }
    }
    public int Id { get; set; }    
    public string Description
    {
        get => _description;
        set
        {
            _description = value; 
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

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

Form code

public partial class Form1 : Form
{
    private readonly BindingSource _bindingSource = new BindingSource();
    private BindingList<Item> _bindingList;
    public Form1()
    {
        InitializeComponent();
        Shown  = OnShown;
    }
    
    private void OnShown(object sender, EventArgs e)
    {

        _bindingList = new BindingList<Item>(new List<Item>()
        {
            new Item() {Selected = false,Id = 1,Description = "A"},
            new Item() {Selected = false,Id = 2,Description = "B"},
            new Item() {Selected = false,Id = 3,Description = "B"},
            new Item() {Selected = false,Id = 4,Description = "A"},
        });

        _bindingSource.DataSource = _bindingList;
        dataGridView1.DataSource = _bindingSource;
        dataGridView1.Columns["Id"]!.ReadOnly = true;
        dataGridView1.CellContentClick  = DataGridView1OnCellContentClick;
    }

    private void DataGridView1OnCellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        if (e.RowIndex < 0 || e.ColumnIndex != 0) return;

        dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);

        for (int index = 0; index < _bindingList.Count; index  )
        {
            if (_bindingList[index].Selected)
            {
                // TODO
            }
            else
            {
                // TODO
            }
        }
    }
}
  • Related