如何有作为的复选框中的dataGridView的columnHeader [英] How to have Checkbox as ColumnHeader of dataGridView

查看:138
本文介绍了如何有作为的复选框中的dataGridView的columnHeader的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在开发C#VS2005的窗口的应用程序。我有一个DataGridView,其中第一列具有复选框。现在我想列标题也是为了如果我选择全部在列Checkboxex应该得到其中选择一个复选框。
我怎样才能做到这一点?
我提到

I'm developing a window application in C# VS2005. I have a dataGridView in which the first column has Checkboxes. Now i want the Column header also to be a CheckBox which if i select all the Checkboxex in the column should get selected. How can i do this.? I referred the Code Project link

但是,如果我使用的,如果我请点击 FirstCell(不是标题)越来越选中所有单元格下面。但我想在列标题中的复选框。我怎样才能做到这一点?

But if i use that, if i click the FirstCell (not the Header) all the below cells are getting selected. But i want a CheckBox in the Column header. How can i do this.?

推荐答案

我也需要有一个复选框 DataGridView的列的列标题。以下是我做的:

I also needed to have a CheckBox in the column header of a DataGridView column. Here's how I did it:


  • 创建从 DataGridViewColumnHeaderCell
  • 在内部使用 System.Windows.Forms.CheckBox 来存储的选中状态,并提供操作系统风格的视觉复选框表示。

  • 使用一个位图作为缓冲,并绘制普通的复选框就可以了(使用 CheckBox.DrawToBitmap

  • 覆盖 DataGridViewColumnHeaderCell.Paint ,如有必要,绘制缓冲区之前更新缓冲区中的图形油漆供应

  • 提供的衍生 DataGridViewColumnHeaderCell ,还有一个的CheckedChanged事件

  • 替换一个Checked属性派生 DataGridViewColumnHeaderCell 列的 HeaderCell DataGridView的是被填充。

  • 检查,并取消复选框当它被列标题点击,只有鼠标点击边界内在复选框

  • 的实施检查所有/取消,所有的派生类之外通过听的CheckedChanged 事件,更新基础数据对象,然后调用 ResetBindings 更新 DataGridView的

  • Create a class which inherits from DataGridViewColumnHeaderCell
  • Internally use a System.Windows.Forms.CheckBox to store the checked state and provide the OS styled visual CheckBox representation.
  • Use a Bitmap as a buffer and draw the regular CheckBox on it (using CheckBox.DrawToBitmap)
  • Override DataGridViewColumnHeaderCell.Paint and, if necessary, update the buffer before drawing the buffer to the Graphics supplied by Paint
  • Provide a Checked property on the derived DataGridViewColumnHeaderCell, and also a CheckedChanged event
  • Substitute the derived DataGridViewColumnHeaderCell in the column's HeaderCell when the DataGridView is being populated.
  • Check and uncheck the CheckBox when it is the column header is clicked, only if the mouse click is within the bounds of the CheckBox
  • Implement the check-all/uncheck-all outside of the derived class by listening to the CheckedChanged event, updating the underlying data object and then calling ResetBindings to update the DataGridView

下面是我写的类,它是从 DataGridViewColumnHeaderCell 来源:

Here's the class I wrote which is derived from DataGridViewColumnHeaderCell:

class DataGridViewCheckBoxColumnHeaderCell : DataGridViewColumnHeaderCell
{
    private Bitmap buffer;
    private CheckBox checkBox;
    private Rectangle checkBoxBounds;

    public DataGridViewCheckBoxColumnHeaderCell()
    {
        this.checkBox = new CheckBox();
    }

    public event EventHandler CheckedChanged;

    public bool Checked
    {
        get 
        { 
            return this.checkBox.Checked; 
        }

        set
        {
            if (!this.Checked == value)
            {
                this.checkBox.Checked = value;
                if (this.buffer != null)
                {
                    this.buffer.Dispose();
                    this.buffer = null;
                }

                this.OnCheckedChanged(EventArgs.Empty);

                if (this.DataGridView != null)
                {
                    this.DataGridView.Refresh();
                }
            }
        }
    }

    protected override void Paint(
        Graphics graphics, 
        Rectangle clipBounds, 
        Rectangle cellBounds, 
        int rowIndex, 
        DataGridViewElementStates dataGridViewElementState, 
        object value, 
        object formattedValue, 
        string errorText, 
        DataGridViewCellStyle cellStyle, 
        DataGridViewAdvancedBorderStyle advancedBorderStyle, 
        DataGridViewPaintParts paintParts)
    {
        // Passing String.Empty in place of 
        // value and formattedValue prevents 
        // this header cell from having text.

        base.Paint(
            graphics, 
            clipBounds, 
            cellBounds, 
            rowIndex, 
            dataGridViewElementState, 
            String.Empty, 
            String.Empty, 
            errorText, 
            cellStyle, 
            advancedBorderStyle, 
            paintParts);

        if (this.buffer == null 
            || cellBounds.Width != this.buffer.Width
            || cellBounds.Height != this.buffer.Height)
        {
            this.UpdateBuffer(cellBounds.Size);
        }

        graphics.DrawImage(this.buffer, cellBounds.Location);
    }

    protected override Size GetPreferredSize(
        Graphics graphics, 
        DataGridViewCellStyle cellStyle, 
        int rowIndex, 
        Size constraintSize)
    {
        return this.checkBox.GetPreferredSize(constraintSize);
    }

    protected override void OnMouseClick(DataGridViewCellMouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left 
            && this.checkBoxBounds.Contains(e.Location))
        {
            this.Checked = !this.Checked;
        }

        base.OnMouseClick(e);
    }

    private void UpdateBuffer(Size size)
    {
        Bitmap updatedBuffer = new Bitmap(size.Width, size.Height);

        this.checkBox.Size = size;

        if (this.checkBox.Size.Width > 0 && this.checkBox.Size.Height > 0)
        {
            Bitmap renderedCheckbox = new Bitmap(
                this.checkBox.Width, 
                this.checkBox.Height);

            this.checkBox.DrawToBitmap(
                renderedCheckbox, 
                new Rectangle(new Point(), this.checkBox.Size));

            MakeTransparent(renderedCheckbox, this.checkBox.BackColor);
            Bitmap croppedRenderedCheckbox = AutoCrop(
                renderedCheckbox, 
                Color.Transparent);

            // TODO implement alignment, right now it is always
            // MiddleCenter regardless of this.Style.Alignment

            this.checkBox.Location = new Point(
                (updatedBuffer.Width - croppedRenderedCheckbox.Width) / 2, 
                (updatedBuffer.Height - croppedRenderedCheckbox.Height) / 2);

            Graphics updatedBufferGraphics = Graphics.FromImage(updatedBuffer);
            updatedBufferGraphics.DrawImage(
                croppedRenderedCheckbox, 
                this.checkBox.Location);

            this.checkBoxBounds = new Rectangle(
                this.checkBox.Location, 
                croppedRenderedCheckbox.Size);

            renderedCheckbox.Dispose();
            croppedRenderedCheckbox.Dispose();
        }

        if (this.buffer != null)
        {
            this.buffer.Dispose();
        }

        this.buffer = updatedBuffer;
    }

    protected virtual void OnCheckedChanged(EventArgs e)
    {
        EventHandler handler = this.CheckedChanged;
        if (handler != null)
        {
            handler(this, e);
        }
    }

    // The methods below are helper methods for manipulating Bitmaps

    private static void MakeTransparent(Bitmap bitmap, Color transparencyMask)
    {
        int transparencyMaskArgb = transparencyMask.ToArgb();
        int transparentArgb = Color.Transparent.ToArgb();

        List deadColumns = new List();

        for (int x = 0; x = 0; x--)
        {
            if (deadColumns.Count == bitmap.Height)
            {
                break;
            }

            for (int y = bitmap.Height - 1; y >= 0; y--)
            {
                if (deadColumns.Contains(y))
                {
                    continue;
                }

                int pixel = bitmap.GetPixel(x, y).ToArgb();

                if (pixel == transparencyMaskArgb)
                {
                    bitmap.SetPixel(x, y, Color.Transparent);
                }
                else if (pixel != transparentArgb)
                {
                    deadColumns.Add(y);
                    break;
                }
            }
        }
    }

    public static Bitmap AutoCrop(Bitmap bitmap, Color backgroundColor)
    {
        Size croppedSize = bitmap.Size;
        Point cropOrigin = new Point();
        int backgroundColorToArgb = backgroundColor.ToArgb();

        for (int x = bitmap.Width - 1; x >= 0; x--)
        {
            bool allPixelsAreBackgroundColor = true;
            for (int y = bitmap.Height - 1; y >= 0; y--)
            {
                if (bitmap.GetPixel(x, y).ToArgb() != backgroundColorToArgb)
                {
                    allPixelsAreBackgroundColor = false;
                    break;
                }
            }

            if (allPixelsAreBackgroundColor)
            {
                croppedSize.Width--;
            }
            else
            {
                break;
            }
        }

        for (int y = bitmap.Height - 1; y >= 0; y--)
        {
            bool allPixelsAreBackgroundColor = true;
            for (int x = bitmap.Width - 1; x >= 0; x--)
            {
                if (bitmap.GetPixel(x, y).ToArgb() != backgroundColorToArgb)
                {
                    allPixelsAreBackgroundColor = false;
                    break;
                }
            }

            if (allPixelsAreBackgroundColor)
            {
                croppedSize.Height--;
            }
            else
            {
                break;
            }
        }

        for (int x = 0; x = 0 && xWhole = 0)
                {
                    bitmapSection.SetPixel(x, y, bitmap.GetPixel(xWhole, yWhole));
                }
                else
                {
                    bitmapSection.SetPixel(x, y, Color.Transparent);
                }
            }
        }

        return bitmapSection;
    }
}

这篇关于如何有作为的复选框中的dataGridView的columnHeader的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆