gpt4 book ai didi

c# - 如何将复选框作为 dataGridView 的 ColumnHeader

转载 作者:可可西里 更新时间:2023-11-01 08:55:01 29 4
gpt4 key购买 nike

我正在使用 C# VS2005 开发一个窗口应用程序。我有一个 dataGridView,其中第一列有复选框。现在我希望列标题也成为一个复选框,如果我选择列中的所有 Checkboxex 应该被选中。我怎样才能做到这一点。?我提到了 Code Project link

但是如果我使用它,如果我单击 FirstCell(不是页眉),下面的所有单元格都会被选中。但我想在列标题中有一个复选框。我该怎么做?

最佳答案

我还需要在 DataGridView 列的列标题中有一个 CheckBox。这是我的做法:

  • 创建一个继承自 DataGridViewColumnHeaderCell 的类
  • 在内部使用 System.Windows.Forms.CheckBox 来存储选中状态并提供操作系统风格的视觉 CheckBox 表示。
  • 使用 Bitmap 作为缓冲区并在其上绘制常规 CheckBox(使用 CheckBox.DrawToBitmap)
  • 重写 DataGridViewColumnHeaderCell.Paint,如有必要,在将缓冲区绘制到 Paint 提供的 Graphics 之前更新缓冲区
  • 在派生的 DataGridViewColumnHeaderCell 上提供一个 Checked 属性,以及一个 CheckedChanged 事件
  • 在填充 DataGridView 时,在列的 HeaderCell 中替换派生的 DataGridViewColumnHeaderCell
  • 在单击列标题时选中和取消选中 CheckBox,前提是鼠标单击在 CheckBox 的范围内
  • 通过监听 CheckedChanged 事件,更新底层数据对象,然后调用 ResetBindings 来更新DataGridView

这是我编写的派生自 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;
}
}

关于c# - 如何将复选框作为 dataGridView 的 ColumnHeader,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/868654/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com