使用Radiobutton列创建DataGridView

时间:2012-07-27 20:46:48

标签: c# datagridview datagridviewcolumn

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

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

我已附加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");
                }
            }
        }
    }
}

更新 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;
        }
    }
}

如果有人可以看一下这个并指出我应该在代码中做了哪些更改的正确方向,我将不胜感激。

谢谢。

1 个答案:

答案 0 :(得分:2)

开始编辑单元格时会发生什么?它变成了一个单选按钮。

这是因为你从一个复选框单元派生而来,它将自己描绘成一个复选框。

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

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

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

<强>更新

ControlPaint课程可以帮助你。