C# WinForm下DataGridView单元按钮列

 我来答
户如乐9318
2022-11-26 · TA获得超过6657个赞
知道小有建树答主
回答量:2559
采纳率:100%
帮助的人:139万
展开全部

  在C# WinForm下做过项目的朋友都知道 其中的DataGridView控件默认只支持DataGridViewButtonColumn DataGridViewCheckBoxColumn DataGridViewComboBoxColumn DataGridViewImageColumn DataGridViewLinkColumn和DataGridViewTextBoxColumn六种列类型 如果你想要在DataGridView的列中添加其它的子控件 则需要自己实现DataGridViewColumn和DataGridViewCell 这就意味着你需要从现有的列中继承并改写一些方法 如实现一个支持单选按钮的列 或支持三种选择状态的多选按钮的列

  

       上面两个截图分别为RadioButton列和支持三种状态的CheckBox列在DataGridView中的实现效果 我是在Windows 中实现的 因此显示的效果跟在XP和Vista下有些区别 Vista下CheckBox的第三种状态(不确定状态)显示出来的效果是一个实心的蓝色方块

  下面我看具体来看看如何实现这两种效果

  要实现自定义的DataGridView列 你需要继承并改写两个类 一个是基于DataGridViewColumn的 一个是基于DataGridViewCell的 因为RadionButton和CheckBox的实现原理类似 因此我们可以将这两种列采用同一种方法实现 创建DataGridViewDisableCheckBoxCell和DataGridViewDisableCheckBoxColumn两个类 分别继承自DataGridViewCheckBoxCell和DataGridViewCheckBoxColumn 代码如下

  public class DataGridViewDisableCheckBoxCell: DataGridViewCheckBoxCell{    public bool Enabled { get; set; }

  // Override the Clone method so that the Enabled property is copied     public override object Clone()    {        DataGridViewDisableCheckBoxCell cell = (DataGridViewDisableCheckBoxCell)base Clone();        cell Enabled = this Enabled;        return cell;    }

  // By default enable the CheckBox cell     public DataGridViewDisableCheckBoxCell()    {        this Enabled = true;    }

  // Three state checkbox column cell    protected override void Paint(Graphics graphics Rectangle clipBounds Rectangle cellBounds int rowIndex         DataGridViewElementStates elementState object value object formattedValue string errorText         DataGridViewCellStyle cellStyle DataGridViewAdvancedBorderStyle advancedBorderStyle DataGridViewPaintParts paintParts)    {        // The checkBox cell is disabled so paint the border background and disabled checkBox for the cell         if (!this Enabled)        {            // Draw the cell background if specified             if ((paintParts & DataGridViewPaintParts Background) == DataGridViewPaintParts Background)            {                SolidBrush cellBackground = new SolidBrush(cellStyle BackColor);                graphics FillRectangle(cellBackground cellBounds);                cellBackground Dispose();            }

  // Draw the cell borders if specified             if ((paintParts & DataGridViewPaintParts Border) == DataGridViewPaintParts Border)            {                PaintBorder(graphics clipBounds cellBounds cellStyle advancedBorderStyle);            }

  // Calculate the area in which to draw the checkBox             CheckBoxState state = CheckBoxState MixedDisabled;            Size size = CheckBoxRenderer GetGlyphSize(graphics state);            Point center = new Point(cellBounds X cellBounds Y);            center X += (cellBounds Width size Width) / ;            center Y += (cellBounds Height size Height) / ;

  // Draw the disabled checkBox             CheckBoxRenderer DrawCheckBox(graphics center state);        }        else        {            // The checkBox cell is enabled so let the base class handle the painting             base Paint(graphics clipBounds cellBounds rowIndex elementState value formattedValue errorText cellStyle advancedBorderStyle paintParts);        }    }}

  public class DataGridViewDisableCheckBoxColumn : DataGridViewCheckBoxColumn{    public DataGridViewDisableCheckBoxColumn()    {        this CellTemplate = new DataGridViewDisableCheckBoxCell();    }}       主要是要实现DataGridViewDisableCheckBoxCell的呈现方式 其中设置了CheckBoxState的状态为MixedDisabled 表示支持三种状态 这个是实现效果的核心 如果要实现RadioButton列的效果 只需要将Paint方法改成下面这样即可

  protected override void Paint(Graphics graphics Rectangle clipBounds Rectangle cellBounds int rowIndex DataGridViewElementStates elementState object value object formattedValue string errorText DataGridViewCellStyle cellStyle DataGridViewAdvancedBorderStyle advancedBorderStyle DataGridViewPaintParts paintParts)    {        // Draw the cell background if specified         if ((paintParts & DataGridViewPaintParts Background) == DataGridViewPaintParts Background)        {            SolidBrush cellBackground = new SolidBrush(cellStyle BackColor);            graphics FillRectangle(cellBackground cellBounds);            cellBackground Dispose();        }

  // Draw the cell borders if specified         if ((paintParts & DataGridViewPaintParts Border) == DataGridViewPaintParts Border)        {            PaintBorder(graphics clipBounds cellBounds cellStyle advancedBorderStyle);        }

  // Calculate the area in which to draw the checkBox         RadioButtonState state = value != null && (SelectedStatus)value == SelectedStatus Selected ? RadioButtonState CheckedNormal : RadioButtonState UncheckedNormal;        Size size = RadioButtonRenderer GetGlyphSize(graphics state);        Point center = new Point(cellBounds X cellBounds Y);        center X += (cellBounds Width size Width) / ;        center Y += (cellBounds Height size Height) / ;

  // Draw the disabled checkBox         RadioButtonRenderer DrawRadioButton(graphics center state);    }      使用RadioButtonState代替CheckBoxState

  当然 上面的代码只是实现了列和单元格的显示效果 在使用过程中当用户点击单选或多选按钮时如何改变状态则需要自己手动编写代码来实现 如在点击单选按钮时将DataGridView中其它行的单选按钮设置为未选择状态 点击多选按钮时在三种状态之间转换等

  首先我们需要手动修改Form的Designer cs文件中的代码 将CheckBox所在的列的类型由DataGridViewCheckBoxColumn改成DataGridViewDisableCheckBoxColumn 并设置ThreeState的值为true 这个代码是需要手动去修改的 因为默认情况下VS不支持对自定义DataGridView列类型进行可视化编辑 要支持CheckBox的三种状态 我们还需要定义一个枚举来给CheckBox的TrueValue FalseValue和IndeterminateValue赋值 这个枚举很简单 有三个成员就够了

  public enum SelectedStatus{     Selected     NoSelected     Indeterminate}      然后设置CheckBox的TrueValue=SelectedStatus Selected FalseValue=SelectedStatus NoSelected IndeterminateValue=SelectedStatus Indeterminate

  好了!这个时候运行程序 可以看到经过我们改造的列已经可以正常显示了 但是有一个问题

  那就是当我们点击其中的单选或多选按钮时它的状态并不能发生变化 这是因为我们没有在click事件中改变按钮的选择状态 要实现这个功能 你需要给宿主DataGridView定义CellContentClick事件 并且判断当用户点击的是否为你所指定的控件 然后进行相应的处理 代码如下

  private void dataGridView _CellContentClick(object sender DataGridViewCellEventArgs e){    if (e RowIndex >= )    {        DataGridViewColumn column = dataGridView Columns[e ColumnIndex];

  if (column is DataGridViewCheckBoxColumn)        {            DataGridViewDisableCheckBoxCell cell = dataGridView Rows[e RowIndex] Cells[e ColumnIndex] as DataGridViewDisableCheckBoxCell;            if (!cell Enabled)            {                return;            }            if ((SelectedStatus)cell Value == SelectedStatus NoSelected)            {                cell Value = SelectedStatus Selected;            }            else if ((SelectedStatus)cell Value == SelectedStatus Selected)            {                cell Value = SelectedStatus Indeterminate;            }            else            {                cell Value = SelectedStatus NoSelected;            }        }    }}       这个是CheckBox的 如果是RadioButton的话你还需要控制其它RadionButton的状态 这个时候就没有三种状态而是两种状态了 代码可以修改成这样

  private void dataGridView _CellContentClick(object sender DataGridViewCellEventArgs e){    if (e RowIndex >= )    {        DataGridViewColumn column = dataGridView Columns[e ColumnIndex];

  if (column is DataGridViewCheckBoxColumn)        {            DataGridViewDisableCheckBoxCell cell = dataGridView Rows[e RowIndex] Cells[e ColumnIndex] as DataGridViewDisableCheckBoxCell;            if (!cell Enabled)            {                return;            }            if ((SelectedStatus)cell Value == SelectedStatus NoSelected)            {                cell Value = SelectedStatus Selected;                SetRadioButtonValue(cell);            }            else            {                cell Value = SelectedStatus NoSelected;            }        }    }}

  private void SetRadioButtonValue(DataGridViewDisableCheckBoxCell cell){    SelectedStatus status = (SelectedStatus)cell Value;    if (status == SelectedStatus Selected)    {        status = SelectedStatus NoSelected;    }    else    {        status = SelectedStatus Selected;    }    for (int i = ; i < dataGridView Rows Count; i++)    {        DataGridViewDisableCheckBoxCell cel = dataGridView Rows[i] Cells[ checkbox ] as DataGridViewDisableCheckBoxCell;        if (!cel Equals(cell))        {            cel Value = status;        }    }}      函数SetRadionButtonValue负责修改宿主DataGridView当前列中其它的RadionButton的状态

  在完成这些工作后 一个相对完整的支持RadionButton或三种状态的CheckBox列的DataGridView界面就完成了 你可以根据需要在接下来的代码中来判断DataGridView中哪些行被选中了 或者哪些行处于未确定的选择状态(CheckBox的第三种状态) 进而做出判断来完成后面的工作

lishixinzhi/Article/program/net/201311/11638

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式