4

我正在尝试创建一个由 Radiobuttons 托管的 DataGridView 列。我一直在关注这篇MSDN 文章。

尽管我已经更改了教程中的代码来编写自己的类,但它并没有按预期工作。问题是我不完全确定我错过了什么。编译时不会出错。但它显示为复选框而不是单选按钮。在此处输入图像描述

我已在此处附加了 Visual Studio 项目。对于那些不确定下载未知附件的人,这里是我写的 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;
        }
    }
}

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

谢谢你。

4

1 回答 1

2

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

这是因为您从一个将自身绘制为复选框的复选框单元格派生而来。

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

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

示例代码不必这样做,因为文本框单元格知道如何绘制文本。

更新

ControlPaint类可以帮助您。

于 2012-07-27T22:54:31.763 回答