DataGridView 复选框选择

发布于 2024-08-31 14:31:21 字数 234 浏览 5 评论 0原文

我将 datagridview 添加到我的 win forms 应用程序中,还添加了一个 CheckBox 用于标记行。 CheckBox 按我的预期工作,直到用户对 DataGridView 进行排序。排序后,之前选择的复选框列将丢失。

有没有办法让我的 datagridview 记住排序后选择了哪一行?

I added datagridview to my win forms app and I also added one CheckBox for marking rows.
The CheckBox works as I expected until the user sorts the DataGridView. After the sort the previous selection of checkbox column is lost.

Is there a way I can make my datagridview remember which row is selected after sorting?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

荭秂 2024-09-07 14:31:21

您有两种选择来解决此问题。

第一个也可能是最简单的是将复选框列绑定到数据源。例如,如果您使用 DataTable 作为数据源,则添加布尔列将在 DataGridView 上创建一个复选框,该复选框将排序且不会丢失选中状态。

如果这不是一个选项,那么解决问题的另一种方法是将 DataGridView 设置为虚拟模式并维护复选框值的缓存。

查看精彩的 DataGridView 常见问题解答 有关如何执行此操作的示例。我还提供了下面的代码,但请查看常见问题解答:

private System.Collections.Generic.Dictionary<int, bool> checkState;
private void Form1_Load(object sender, EventArgs e)
{
    dataGridView1.AutoGenerateColumns = false;
    dataGridView1.DataSource = customerOrdersBindingSource;

    // The check box column will be virtual.
    dataGridView1.VirtualMode = true;
    dataGridView1.Columns.Insert(0, new DataGridViewCheckBoxColumn());

    // Initialize the dictionary that contains the boolean check state.
    checkState = new Dictionary<int, bool>();
}
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    // Update the status bar when the cell value changes.
    if (e.ColumnIndex == 0 && e.RowIndex != -1)
    {
        // Get the orderID from the OrderID column.
        int orderID = (int)dataGridView1.Rows[e.RowIndex].Cells["OrderID"].Value;
        checkState[orderID] = (bool)dataGridView1.Rows[e.RowIndex].Cells[0].Value;
    }    
}

private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
    // Handle the notification that the value for a cell in the virtual column
    // is needed. Get the value from the dictionary if the key exists.

    if (e.ColumnIndex == 0)
    {
        int orderID = (int)dataGridView1.Rows[e.RowIndex].Cells["OrderID"].Value;
        if (checkState.ContainsKey(orderID))
            e.Value = checkState[orderID];
        else
            e.Value = false;
    }

}

private void dataGridView1_CellValuePushed(object sender, DataGridViewCellValueEventArgs e)
{
    // Handle the notification that the value for a cell in the virtual column
    // needs to be pushed back to the dictionary.

    if (e.ColumnIndex == 0)
    {
        // Get the orderID from the OrderID column.
        int orderID = (int)dataGridView1.Rows[e.RowIndex].Cells["OrderID"].Value;

        // Add or update the checked value to the dictionary depending on if the 
        // key (orderID) already exists.
        if (!checkState.ContainsKey(orderID))
        {
            checkState.Add(orderID, (bool)e.Value);
        }
        else
            checkState[orderID] = (bool)e.Value;
    }
}

You have two options to solve this issue.

The first and possibly the most simple is to bind your checkbox column to your datasource. For example, if you are using a DataTable as your datasource, adding a boolean column will create a checkbox on your DataGridView that will sort and not lose the checked state.

If this is not an option then the other way of addressing the problem is to set your DataGridView to Virtual mode and maintain a cache of your checkbox values.

Check out the excellent DataGridView FAQ for an example of how to do this. I've also provided the code below but do check out the FAQ:

private System.Collections.Generic.Dictionary<int, bool> checkState;
private void Form1_Load(object sender, EventArgs e)
{
    dataGridView1.AutoGenerateColumns = false;
    dataGridView1.DataSource = customerOrdersBindingSource;

    // The check box column will be virtual.
    dataGridView1.VirtualMode = true;
    dataGridView1.Columns.Insert(0, new DataGridViewCheckBoxColumn());

    // Initialize the dictionary that contains the boolean check state.
    checkState = new Dictionary<int, bool>();
}
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    // Update the status bar when the cell value changes.
    if (e.ColumnIndex == 0 && e.RowIndex != -1)
    {
        // Get the orderID from the OrderID column.
        int orderID = (int)dataGridView1.Rows[e.RowIndex].Cells["OrderID"].Value;
        checkState[orderID] = (bool)dataGridView1.Rows[e.RowIndex].Cells[0].Value;
    }    
}

private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
    // Handle the notification that the value for a cell in the virtual column
    // is needed. Get the value from the dictionary if the key exists.

    if (e.ColumnIndex == 0)
    {
        int orderID = (int)dataGridView1.Rows[e.RowIndex].Cells["OrderID"].Value;
        if (checkState.ContainsKey(orderID))
            e.Value = checkState[orderID];
        else
            e.Value = false;
    }

}

private void dataGridView1_CellValuePushed(object sender, DataGridViewCellValueEventArgs e)
{
    // Handle the notification that the value for a cell in the virtual column
    // needs to be pushed back to the dictionary.

    if (e.ColumnIndex == 0)
    {
        // Get the orderID from the OrderID column.
        int orderID = (int)dataGridView1.Rows[e.RowIndex].Cells["OrderID"].Value;

        // Add or update the checked value to the dictionary depending on if the 
        // key (orderID) already exists.
        if (!checkState.ContainsKey(orderID))
        {
            checkState.Add(orderID, (bool)e.Value);
        }
        else
            checkState[orderID] = (bool)e.Value;
    }
}
鸠书 2024-09-07 14:31:21

我很惊讶这种情况发生,但如果在最坏的情况下没有其他方法,您可以将排序设置为编程式,然后在用户单击列标题时进行处理,保存检查项目的列表,执行以编程方式排序,然后检查任何应检查的项目。

I'm surprised that that happens, but if there's no other way around it in a worst case you could set the sorting to programmatic and then handle when the user clicks on the column header, save a list of which items are checked, do the sorting programmatically and then check any items that should be checked.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文