我正在嘗試選擇所有復選框,但它有一個錯誤。
如果在選擇包含復選框的列時單擊頂部的完整檢查/釋放復選框,則所選區域不會更改。
我該如何解決?

上圖是點擊完整版后。
這是我的測驗代碼。
函式 dataGridView1_CellPainting() 和 dgvCheckBox_CheckedChanged() 用于完整的檢查/釋放操作。
namespace TestWinForm
{
public partial class Form1 : Form
{
List<string> saved_file_names = new List<string>();
int table_index = 0;
public Form1()
{
InitializeComponent();
}
private void add_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "??";
ofd.Filter = "txt?? | *.txt";
ofd.Multiselect = true; // ?? ?? ??
DialogResult dr = ofd.ShowDialog();
if (dr == DialogResult.OK)
{
foreach (string file_name in ofd.FileNames)
{
// 1. ????
if (saved_file_names.Contains(file_name))
continue;
// 2. ?????? ???? ??.
dataGridView1.Rows.Add();
dataGridView1.Rows[table_index].Cells[1].Value = table_index 1;
dataGridView1.Rows[table_index].Cells[2].Value = file_name;
saved_file_names.Add(file_name);
dataGridView1.Rows[table_index].Cells[3].Value = "none";
table_index ;
}
}
}
private void delete_Click(object sender, EventArgs e)
{
bool is_checked = false;
List<int> delete_index = new List<int>();
for (int i = 0; i < table_index; i )
{
if (Convert.ToBoolean(dataGridView1.Rows[i].Cells[0].Value) == true)
delete_index.Add(i);
}
if (delete_index.Count == 0)
return;
delete_index.Reverse();
foreach (var index in delete_index)
{
table_index--;
saved_file_names.RemoveAt(index);
dataGridView1.Rows.RemoveAt(index);
}
}
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex == 0 && e.RowIndex == -1)
{
e.PaintBackground(e.ClipBounds, false);
Point pt = e.CellBounds.Location;
int nChkBoxWidth = 15;
int nChkBoxHeight = 15;
int offsetx = (e.CellBounds.Width - nChkBoxWidth) / 2;
int offsety = (e.CellBounds.Height - nChkBoxHeight) / 2;
pt.X = offsetx;
pt.Y = offsety;
CheckBox cb = new CheckBox();
cb.Size = new Size(nChkBoxWidth, nChkBoxHeight);
cb.Location = pt;
cb.Checked = true;
cb.CheckedChanged = new EventHandler(dgvCheckBox_CheckedChanged);
((DataGridView)sender).Controls.Add(cb);
e.Handled = true;
}
}
private void dgvCheckBox_CheckedChanged(object sender, EventArgs e)
{
foreach (DataGridViewRow r in dataGridView1.Rows)
{
r.Cells[0].Value = ((CheckBox)sender).Checked;
}
}
}
}
uj5u.com熱心網友回復:
請考慮將資料系結與您一起使用,DataGridView這可以簡化您嘗試做的事情。通過使用您的屬性定義一個Record類,當您將該記錄添加到這些記錄的系結串列時bool IsChecked,會自動創建復選框行。然后,您可以通過在記錄中設定屬性而不是呼叫 UI 物件本身來操作該檢查。
單擊標題單元格:
- 如果選中或未選中全部,則全部都將切換。
- 如果混合了選中和未選中,那么所有將被提升為選中。
這是GitHub 上的一個作業示例。
using System;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
namespace dgv_ac
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// Wait for the main form to be created, then attach
/// your Binding List as the data source of the DGV
/// </summary>
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
dataGridView1.DataSource = this.DataSource;
initDGV();
}
private void initDGV()
{
dataGridView1.AllowUserToAddRows = false;
// Now you can populate the DataGridView simply
// by adding some records to the list.
for (int i = 0; i < 5; i )
{
DataSource.Add(new Record { Number = i, FileName = $"MyFile_{i}.txt" });
}
// Once the first record is added, the Columns information is
// available and we can do column formatting.
dataGridView1.Columns[nameof(Record.FileName)].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
var checkboxColumn = dataGridView1.Columns[nameof(Record.IsChecked)];
checkboxColumn.HeaderText = string.Empty;
checkboxColumn.Width = 40;
dataGridView1.CellClick = onCellClick;
dataGridView1.CellContentClick = onCellContentClick;
}
/// <summary>
/// Detect check box click and end the edit mode in this case.
/// </summary>
private void onCellContentClick(object sender, DataGridViewCellEventArgs e)
{
if(e.RowIndex != -1)
{
var cell = dataGridView1[e.ColumnIndex, e.RowIndex];
if(cell is DataGridViewCheckBoxCell checkbox)
{
dataGridView1.EndEdit();
}
}
}
/// <summary>
/// Detect header click and set the records accordingly.
/// </summary>
private void onCellClick(object sender, DataGridViewCellEventArgs e)
{
if(e.RowIndex == -1)
{
switch (dataGridView1.Columns[e.ColumnIndex].Name)
{
case nameof(Record.IsChecked):
if (DataSource.Any()) // Check to see if there are any records at all.
{
if(DataSource.Count(record=>record.IsChecked) == DataSource.Count)
{
// This block says thet're all chacked or all unchecked.
if(DataSource.First().IsChecked) // then they all are
{
setAll(false);
}
else
{
setAll(true);
}
}
else setAll(true); // If they're mixed, make them all checked.
}
break;
}
}
void setAll(bool value)
{
foreach (var record in DataSource)
{
record.IsChecked = value;
}
Refresh();
}
}
public BindingList<Record> DataSource = new BindingList<Record>();
}
// This is the record class that will provide column
// information to the DataGridView automatically.
public class Record
{
public int Number { get; set; }
public bool IsChecked { get; set; }
public string FileName { get; set; }
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/477903.html
上一篇:DockerDesktop記憶體限制究竟適用于什么?
下一篇:在C#中鍵入種姓Serilog
