c# – 使用Radiobutton列创建DataGridView

我正在尝试创建一个使用Radiobuttons托管的DataGridView列.我一直关注
this MSDN文章.

虽然我已经从教程中更改了代码来编写自己的类,但它并没有按预期工作.事情是我不完全确定我缺少什么.编译时没有错误.但它显示为Checkboxes而不是Radiobuttons.

我已经附加了Visual Studio项目here.对于那些不确定下载未知附件的人,这里有我写的3个类.

RadiobuttonColumn类.它继承了DataGridViewColumn类.

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    class RadiobuttonColumn : DataGridViewColumn
    {
        public RadiobuttonColumn()
            : base(new RadiobuttonCell())
        {
        }

        public override DataGridViewCell CellTemplate
        {
            get
            {
                return base.CellTemplate;
            }
            set
            {
                if (value != null && !value.GetType().IsAssignableFrom(typeof(RadiobuttonCell)))
                {
                    throw new InvalidCastException("Must be a RadiobuttonCell");
                }
            }
        }
    }
}

UPDATED RadiobuttonCell类继承DataGridViewCell类.

using System;
using System.Windows.Forms;
using System.Drawing;

namespace DataGridView_Radiobutton_column
{
    public class RadiobuttonCell : DataGridViewCell
    {
        public RadiobuttonCell()
            : base()
        { 
        }

        public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
        {
            base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
            RadiobuttonEditingControl rdb = DataGridView.EditingControl as RadiobuttonEditingControl;
            if (this.Value == null)
            {
                rdb.Checked = false;
            }
            else
            {
                rdb.Checked = (Boolean)this.Value;
            }
        }

        public override Type EditType
        {
            get
            {
                return typeof(RadiobuttonEditingControl);
            }
        }

        public override Type ValueType
        {
            get
            {
                return typeof(Boolean);
            }
        }

        public override object DefaultNewRowValue
        {
            get
            {
                return false;
            }
        }

        protected override void Paint(System.Drawing.Graphics graphics, System.Drawing.Rectangle clipBounds, System.Drawing.Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);


            Rectangle rectRadioButton = default(Rectangle);

            rectRadioButton.Width = 14;
            rectRadioButton.Height = 14;
            rectRadioButton.X = cellBounds.X + (cellBounds.Width - rectRadioButton.Width) / 2;
            rectRadioButton.Y = cellBounds.Y + (cellBounds.Height - rectRadioButton.Height) / 2;

            ControlPaint.DrawRadioButton(graphics, rectRadioButton, ButtonState.Normal);
        }
    }
}

RadiobuttonEditingControl类继承RadioButton类并实现IDataGridViewEditingControl接口的方法.

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    class RadiobuttonEditingControl : RadioButton, IDataGridViewEditingControl
    {
        DataGridView dataGridView;
        private bool valueChanged = false;
        int rowIndex;

        public RadiobuttonEditingControl()
        {
            this.Checked = false;
        }

        public object EditingControlFormattedValue
        {
            get
            {
                return this.Checked = true;
            }
            set
            {
                this.Checked = false;
            }
        }

        public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
        {
            return EditingControlFormattedValue;
        }

        public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
        {
        }

        public int EditingControlRowIndex
        {
            get
            {
                return rowIndex;
            }
            set
            {
                rowIndex = value;
            }
        }

        public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey)
        {
            switch (key & Keys.KeyCode)
            {
                case Keys.Space:
                    return true;
                default:
                    return !dataGridViewWantsInputKey;
            }
        }

        public void PrepareEditingControlForEdit(bool selectAll)
        {
        }

        public bool RepositionEditingControlOnValueChange
        {
            get
            {
                return false;
            }
        }

        public DataGridView EditingControlDataGridView
        {
            get
            {
                return dataGridView;
            }
            set
            {
                dataGridView = value;
            }
        }

        public bool EditingControlValueChanged
        {
            get
            {
                return valueChanged;
            }
            set
            {
                valueChanged = value;
            }
        }

        public Cursor EditingPanelCursor
        {
            get
            {
                return base.Cursor;
            }
        }

        protected override void OnCheckedChanged(EventArgs eventArgs)
        {
            valueChanged = true;
            this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
            base.Checked = false;
        }
    }
}

如果有人可以看看这个并指出我在正确的方向上应该在代码中做些什么改变,我将不胜感激.

谢谢.

最佳答案 开始编辑单元格时会发生什么?它变成了一个单选按钮.

这是因为您从复选框单元格派生而来,该单元格将自身绘制为复选框.

DGV不是控制网格.它是一个框的网格,在用户尝试编辑单元格之前,它们被绘制成看起来像控件.此时,DGV将单元格(唯一的)编辑控件移动到位,并使其可供用户与之交互.

您将不得不从基础DataGridViewCell类派生并实现所有绘制代码​​.

示例代码不必执行此操作,因为文本框单元格知道如何绘制文本.

更新

ControlPaint课程可以帮助你.

点赞