C # Add a single-choice or multiple-choice button column to the datagridview control under winform

Source: Internet
Author: User

Anyone who has worked on projects in C # winform knows that the datagridview control only supports six types by default: datagridviewbuttoncolumn, datagridviewcheckboxcolumn, datagridviewcomboboxcolumn, datagridviewimagecolumn, datagridviewlinkcolumn, and datagridviewtextboxcolumn, if you want to add other child controls to the column of the datagridview, You need to implement the datagridviewcolumn and datagridviewcell by yourself. This means that you need to inherit from the existing columns and rewrite some methods, for example, you can implement a column that supports single-choice buttons or columns that support multiple-choice buttons in three selection states.

{
Function onclick ()
{
Get_larger (this)
}
} "Src =" resourse/images/resimages/article/5011/0 .gif" alt = "C # datagridview dview cell button column under winform">

{
Function onclick ()
{
Get_larger (this)
}
} "Src =" resourse/images/resimages/article/5011/1 .gif" alt = "C # datagridview dview cell button column under winform">

The two above are the radiobutton columns and the checkbox columns supporting three states are implemented in the datagridview. I implemented them in Windows 2003, so the displayed results are somewhat different from those in XP and Vista, the third (uncertain) Status of the checkbox in Vista is displayed as a solid blue box.

Next I will take a look at how to achieve these two effects.

To implement a custom datagridview column, you need to inherit and rewrite two classes, one based on the datagridviewcolumn and the other based on the datagridviewcell, because the implementation principles of radionbutton and checkbox are similar, therefore, we can implement these two columns in the same way. Create two classes: datagridviewdisablecheckboxcell and datagridviewdisablecheckboxcolumn, which are inherited from datagridviewcheckboxcell and datagridviewcheckboxcolumn. The Code is as follows:

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();
    }
}

Source: happy life
This site mainly provides a variety of technical articles, resource downloads and Image Browsing.

It is mainly to implement the presentation mode of the datagridviewdisablecheckboxcell. The checkboxstate state is set to mixeddisabled, indicating that three States are supported. This is the core of the implementation effect. If you want to implement the radiobutton column effect, you only need to change the paint Method to the following:

    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);
    }

Use radiobuttonstate instead of checkboxstate.

Of course, the above Code only achieves the Display Effect of columns and cells. In the use process, you need to manually write code to achieve how to change the status when you click one or more select buttons, for example, when you click the single-choice button, set the single-choice button of other rows in the datagridview to the unselected status, and switch between the three States when you click the multiple-choice button.

First, we need to manually modify the designer of the form. the code in the CS file changes the type of the column where the checkbox is located from datagridviewcheckboxcolumn to datagridviewdisablecheckboxcolumn, and sets the value of threestate to true. This code needs to be manually modified, by default, vs does not support visual editing of the custom dview column type. To support three States of the checkbox, we also need to define an enumeration to assign values to the truevalue, falsevalue, and indeterminatevalue of the checkbox. This enumeration is simple. It is enough to have three members.

public enum selectedstatus
{
    selected,
    noselected,
    indeterminate
}

Then set truevalue = selectedstatus. Selected, falsevalue = selectedstatus. noselected, indeterminatevalue = selectedstatus. indeterminate of the checkbox.

Okay! Run the program at this time. We can see that the modified columns are displayed normally, but there is a problem,

That is, when we click one or more select button, its status does not change, because we did not change the button selection status in the click event. To implement this function, you need to define the cellcontentclick event for the host datagridview, and determine whether the user clicks the control you specified, and then perform corresponding processing. The Code is as follows:

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

This is a checkbox. If it is radiobutton, you still need to control the status of other radionbuttons. At this time, there are no three states but two. The code can be changed to this:

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

 

The setradionbuttonvalue function is used to modify the status of other radionbuttons in the current column of the host datagridview.

After completing these tasks, a relatively complete datagridview interface that supports radionbutton or three states of checkbox columns is complete, you can use the following code to determine which rows in the datagridview are selected or which rows are in the unknown selection status (the third status of the checkbox ), then make a judgment to complete the subsequent work.

At last, I will provide the entire project for you to download, which also provides some effects in the datagridviewlinkcolumn column, such as displaying a tooltip when you point to the hyperlink and opening a webpage when you click the hyperlink.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.