datagridview怎样添加单选控件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了datagridview怎样添加单选控件相关的知识,希望对你有一定的参考价值。

在winfrom里的datagridview里添加单选按钮
不是asp.net

datagridview控件默认只支持datagridviewbuttoncolumn、datagridviewcheckboxcolumn、datagridviewcomboboxcolumn、datagridviewimagecolumn、datagridviewlinkcolumn和datagridviewtextboxcolumn六种列类型,如果你想要在datagridview的列中添加其它的子控件,则需要自己实现datagridviewcolumn和datagridviewcell,这就意味着你需要从现有的列中继承并改写一些方法,如实现一个支持单选按钮的列,或支持三种选择状态的多选按钮的列。
要实现自定义的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) / 2;
            center.y += (cellbounds.height - size.height) / 2;

            // 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) / 2;
        center.y += (cellbounds.height - size.height) / 2;

        // 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 datagridview1_cellcontentclick(object sender, datagridviewcelleventargs e)

    if (e.rowindex >= 0)
   
        datagridviewcolumn column = datagridview1.columns[e.columnindex];

        if (column is datagridviewcheckboxcolumn)
       
            datagridviewdisablecheckboxcell cell = datagridview1.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 datagridview1_cellcontentclick(object sender, datagridviewcelleventargs e)

    if (e.rowindex >= 0)
   
        datagridviewcolumn column = datagridview1.columns[e.columnindex];

        if (column is datagridviewcheckboxcolumn)
       
            datagridviewdisablecheckboxcell cell = datagridview1.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 = 0; i < datagridview1.rows.count; i++)
   
        datagridviewdisablecheckboxcell cel = datagridview1.rows[i].cells["checkbox"] as datagridviewdisablecheckboxcell;
        if (!cel.equals(cell))
       
            cel.value = status;
       
   


   函数setradionbuttonvalue负责修改宿主datagridview当前列中其它的radionbutton的状态。

   在完成这些工作后,一个相对完整的支持radionbutton或三种状态的checkbox列的datagridview界面就完成了,你可以根据需要在接下来的代码中来判断datagridview中哪些行被选中了,或者哪些行处于未确定的选择状态(checkbox的第三种状态),进而做出判断来完成后面的工作。
参考技术A datagridview 添加一个列,然后在这个列中显示checkbox按键就OK了,这样的话,你添加数据后面都会有checkbox单选按钮 参考技术B datagridview在添加列时,有个列类型的属性,可以让该列显示复选框的样式,不知道合不合你需求 参考技术C 在datagridview右边的小箭头里面添加 参考技术D 什么意思? 麻烦您说得具体些追问

在winfrom里的datagridview里添加单选按钮
不是asp.net

以上是关于datagridview怎样添加单选控件的主要内容,如果未能解决你的问题,请参考以下文章

dataGridView 如何默认选中第一行

winform dataGridView中如何添加单选按钮列?

C# datagridviewdatagridGridControl增加行号

winform中datagridview控件的列名怎样实现多表头?

如何在一个DataGridView中的一列添加DateTimePicker控件 C#

C# datagridview 怎样动态设置列宽的值