Unbound DataGridViewCheckBoxCell set value

2019-08-29 12:29发布

问题:

I have a problem. My code contains DataGridView and UnBound CheckBoxColumn. My dialog should be for choose rooms from list. For second time you want to see what are you chose in first time.

Code:

ChooseGroupRoomDialog.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BE; // My namespace
using ListExtensions; // My namespace

namespace PLForms
{
    public partial class ChooseGroupRoomsDialog : Form
    {
        public List<Room> Value
        {
            get
            {
                List<Room> retList = new List<Room>();
                for (int i = 0; i < table.RowCount; i++)
                {
                    DataGridViewCheckBoxCell cell = (DataGridViewCheckBoxCell)table[chooseColumnIndex, i];
                    if (cell.Value != null && (bool)cell.Value)
                        retList.Add((Room)table.Rows[i].DataBoundItem);
                }
                return retList;
            }
            set
            {
                List<Room> data = (List<Room>)(table.DataSource);
                foreach (Room room in value)
                {
                    int index = data.FindIndex(roomA => roomA.Id == room.Id);
                    if (index != -1)
                    {
                        table[index, chooseColumnIndex].Value = true; //Not working!!
                    }
                }
            }
        }
        private int chooseColumnIndex;
        public ChooseGroupRoomsDialog(List<Room> dataSource)
        {
            InitializeComponent();
            table.DataSource = dataSource.ToList();
            DialogResult = DialogResult.Cancel;
            foreach (DataGridViewColumn col in table.Columns)
                col.ReadOnly = true;
            chooseColumnIndex = chooseColumn.Index;
            chooseColumn.ReadOnly = false;
        }

        private void okButton_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.OK;
            this.Close();
        }

        private void cancelButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}

ChooseGroupRoomDialog.Designer.cs

namespace PLForms
{
    partial class ChooseGroupRoomsDialog
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
            this.table = new System.Windows.Forms.DataGridView();
            this.roomBindingSource = new System.Windows.Forms.BindingSource(this.components);
            this.okButton = new System.Windows.Forms.Button();
            this.cancelButton = new System.Windows.Forms.Button();
            this.chooseColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn();
            this.idDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.numberOfBedsDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.typeOfRoomStringDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.viewingSeaDataGridViewCheckBoxColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn();
            this.costDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.jakuziDataGridViewCheckBoxColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn();
            this.numberOfWindowsDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.airConditionedDataGridViewCheckBoxColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn();
            this.cleaningDateDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.landScapeDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
            ((System.ComponentModel.ISupportInitialize)(this.table)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.roomBindingSource)).BeginInit();
            this.SuspendLayout();
            // 
            // table
            // 
            this.table.AllowUserToAddRows = false;
            this.table.AllowUserToDeleteRows = false;
            this.table.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.table.AutoGenerateColumns = false;
            this.table.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.table.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.chooseColumn,
            this.idDataGridViewTextBoxColumn,
            this.numberOfBedsDataGridViewTextBoxColumn,
            this.typeOfRoomStringDataGridViewTextBoxColumn,
            this.viewingSeaDataGridViewCheckBoxColumn,
            this.costDataGridViewTextBoxColumn,
            this.jakuziDataGridViewCheckBoxColumn,
            this.numberOfWindowsDataGridViewTextBoxColumn,
            this.airConditionedDataGridViewCheckBoxColumn,
            this.cleaningDateDataGridViewTextBoxColumn,
            this.landScapeDataGridViewTextBoxColumn});
            this.table.DataSource = this.roomBindingSource;
            dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
            dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Window;
            dataGridViewCellStyle1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(177)));
            dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.ControlText;
            dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.GradientInactiveCaption;
            dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.ControlText;
            dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
            this.table.DefaultCellStyle = dataGridViewCellStyle1;
            this.table.Location = new System.Drawing.Point(129, 12);
            this.table.MultiSelect = false;
            this.table.Name = "table";
            this.table.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
            this.table.Size = new System.Drawing.Size(1047, 372);
            this.table.TabIndex = 1;
            // 
            // roomBindingSource
            // 
            this.roomBindingSource.DataSource = typeof(BE.Room);
            // 
            // okButton
            // 
            this.okButton.Location = new System.Drawing.Point(12, 12);
            this.okButton.Name = "okButton";
            this.okButton.Size = new System.Drawing.Size(111, 44);
            this.okButton.TabIndex = 2;
            this.okButton.Text = "אישור";
            this.okButton.UseVisualStyleBackColor = true;
            this.okButton.Click += new System.EventHandler(this.okButton_Click);
            // 
            // cancelButton
            // 
            this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.cancelButton.Location = new System.Drawing.Point(12, 62);
            this.cancelButton.Name = "cancelButton";
            this.cancelButton.Size = new System.Drawing.Size(111, 44);
            this.cancelButton.TabIndex = 2;
            this.cancelButton.Text = "ביטול";
            this.cancelButton.UseVisualStyleBackColor = true;
            this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
            // 
            // chooseColumn
            // 
            this.chooseColumn.HeaderText = "בחירה";
            this.chooseColumn.Name = "chooseColumn";
            this.chooseColumn.Width = 70;
            // 
            // idDataGridViewTextBoxColumn
            // 
            this.idDataGridViewTextBoxColumn.DataPropertyName = "Id";
            this.idDataGridViewTextBoxColumn.HeaderText = "מספר זיהוי";
            this.idDataGridViewTextBoxColumn.Name = "idDataGridViewTextBoxColumn";
            // 
            // numberOfBedsDataGridViewTextBoxColumn
            // 
            this.numberOfBedsDataGridViewTextBoxColumn.DataPropertyName = "NumberOfBeds";
            this.numberOfBedsDataGridViewTextBoxColumn.HeaderText = "מספר מיטות";
            this.numberOfBedsDataGridViewTextBoxColumn.Name = "numberOfBedsDataGridViewTextBoxColumn";
            // 
            // typeOfRoomStringDataGridViewTextBoxColumn
            // 
            this.typeOfRoomStringDataGridViewTextBoxColumn.DataPropertyName = "TypeOfRoomString";
            this.typeOfRoomStringDataGridViewTextBoxColumn.HeaderText = "סוג חדר";
            this.typeOfRoomStringDataGridViewTextBoxColumn.Name = "typeOfRoomStringDataGridViewTextBoxColumn";
            this.typeOfRoomStringDataGridViewTextBoxColumn.ReadOnly = true;
            // 
            // viewingSeaDataGridViewCheckBoxColumn
            // 
            this.viewingSeaDataGridViewCheckBoxColumn.DataPropertyName = "ViewingSea";
            this.viewingSeaDataGridViewCheckBoxColumn.HeaderText = "נוף לים";
            this.viewingSeaDataGridViewCheckBoxColumn.Name = "viewingSeaDataGridViewCheckBoxColumn";
            this.viewingSeaDataGridViewCheckBoxColumn.Width = 70;
            // 
            // costDataGridViewTextBoxColumn
            // 
            this.costDataGridViewTextBoxColumn.DataPropertyName = "Cost";
            this.costDataGridViewTextBoxColumn.HeaderText = "מחיר";
            this.costDataGridViewTextBoxColumn.Name = "costDataGridViewTextBoxColumn";
            this.costDataGridViewTextBoxColumn.ReadOnly = true;
            // 
            // jakuziDataGridViewCheckBoxColumn
            // 
            this.jakuziDataGridViewCheckBoxColumn.DataPropertyName = "Jakuzi";
            this.jakuziDataGridViewCheckBoxColumn.HeaderText = "ג\'קוזי";
            this.jakuziDataGridViewCheckBoxColumn.Name = "jakuziDataGridViewCheckBoxColumn";
            this.jakuziDataGridViewCheckBoxColumn.Width = 70;
            // 
            // numberOfWindowsDataGridViewTextBoxColumn
            // 
            this.numberOfWindowsDataGridViewTextBoxColumn.DataPropertyName = "NumberOfWindows";
            this.numberOfWindowsDataGridViewTextBoxColumn.HeaderText = "מספר חלונות";
            this.numberOfWindowsDataGridViewTextBoxColumn.Name = "numberOfWindowsDataGridViewTextBoxColumn";
            // 
            // airConditionedDataGridViewCheckBoxColumn
            // 
            this.airConditionedDataGridViewCheckBoxColumn.DataPropertyName = "AirConditioned";
            this.airConditionedDataGridViewCheckBoxColumn.HeaderText = "מיזוג אוויר";
            this.airConditionedDataGridViewCheckBoxColumn.Name = "airConditionedDataGridViewCheckBoxColumn";
            this.airConditionedDataGridViewCheckBoxColumn.Width = 80;
            // 
            // cleaningDateDataGridViewTextBoxColumn
            // 
            this.cleaningDateDataGridViewTextBoxColumn.DataPropertyName = "CleaningDate";
            this.cleaningDateDataGridViewTextBoxColumn.HeaderText = "תאריך ניקיון";
            this.cleaningDateDataGridViewTextBoxColumn.Name = "cleaningDateDataGridViewTextBoxColumn";
            // 
            // landScapeDataGridViewTextBoxColumn
            // 
            this.landScapeDataGridViewTextBoxColumn.DataPropertyName = "LandScape";
            this.landScapeDataGridViewTextBoxColumn.HeaderText = "איכות נוף";
            this.landScapeDataGridViewTextBoxColumn.Name = "landScapeDataGridViewTextBoxColumn";
            this.landScapeDataGridViewTextBoxColumn.Width = 90;
            // 
            // ChooseGroupRoomsDialog
            // 
            this.AcceptButton = this.okButton;
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.CancelButton = this.cancelButton;
            this.ClientSize = new System.Drawing.Size(1190, 399);
            this.Controls.Add(this.cancelButton);
            this.Controls.Add(this.okButton);
            this.Controls.Add(this.table);
            this.Name = "ChooseGroupRoomsDialog";
            this.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
            this.RightToLeftLayout = true;
            this.Text = "בחר חדרים";
            ((System.ComponentModel.ISupportInitialize)(this.table)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.roomBindingSource)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.BindingSource roomBindingSource;
        private System.Windows.Forms.DataGridView table;
        private System.Windows.Forms.Button okButton;
        private System.Windows.Forms.Button cancelButton;
        private System.Windows.Forms.DataGridViewCheckBoxColumn chooseColumn;
        private System.Windows.Forms.DataGridViewTextBoxColumn idDataGridViewTextBoxColumn;
        private System.Windows.Forms.DataGridViewTextBoxColumn numberOfBedsDataGridViewTextBoxColumn;
        private System.Windows.Forms.DataGridViewTextBoxColumn typeOfRoomStringDataGridViewTextBoxColumn;
        private System.Windows.Forms.DataGridViewCheckBoxColumn viewingSeaDataGridViewCheckBoxColumn;
        private System.Windows.Forms.DataGridViewTextBoxColumn costDataGridViewTextBoxColumn;
        private System.Windows.Forms.DataGridViewCheckBoxColumn jakuziDataGridViewCheckBoxColumn;
        private System.Windows.Forms.DataGridViewTextBoxColumn numberOfWindowsDataGridViewTextBoxColumn;
        private System.Windows.Forms.DataGridViewCheckBoxColumn airConditionedDataGridViewCheckBoxColumn;
        private System.Windows.Forms.DataGridViewTextBoxColumn cleaningDateDataGridViewTextBoxColumn;
        private System.Windows.Forms.DataGridViewTextBoxColumn landScapeDataGridViewTextBoxColumn;
    }
}

回答1:

Something weird is happening that I can't pin down. When I set a break point on your //Not working!! line, passing in an artificial list of two rooms out of five that I'm populating with, the watch window shows the type of table[index, chooseColumn.Index] as a DataGridViewTextBoxCell the first time and a DataGridViewCheckBoxCell the second, and I'm not even sure how that's possible.

EDIT: I just figured out how it's possible. You have the column and row indices backward. Your non-working line should be:

table[chooseColumn.Index, index].Value = true; //Working!!

EDIT AGAIN: OK, my previous conjectures and link to this answer were also necessary. You have to fix the index order AND set the cell value to true in the DataBindingComplete handler:

    List<Room> _value;
    public List<Room> Value
    {
        get
        {
            List<Room> retList = new List<Room>();
            for (int i = 0; i < table.RowCount; i++)
            {
                DataGridViewCheckBoxCell cell = (DataGridViewCheckBoxCell)table[chooseColumn.Index, i];
                if (cell.Value != null && (bool)cell.Value)
                    retList.Add((Room)table.Rows[i].DataBoundItem);
            }
            return retList;
        }
        set
        {
            _value = value;
        }
    }

    private void table_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
    {
        if (_value == null) return;
        List<Room> data = (List<Room>)(table.DataSource);
        foreach (Room room in _value)
        {
            int index = data.FindIndex(roomA => roomA.Id == room.Id);
            if (index != -1)
            {
                table[chooseColumn.Index, index].Value = true; //Working!!
            }
        }
    }