【问题标题】:Enable selection by ColumnHeader, RowHeader and Cell in DataGridView在 DataGridView 中通过 ColumnHeader、RowHeader 和 Cell 启用选择
【发布时间】:2019-12-19 08:58:20
【问题描述】:

我正在尝试在DataGridView 中实现类似 excel 的功能。所以:

  1. 如果他们选择列标题,它将选择列
  2. 如果用户选择行标题,则将选择整行
  3. 除此之外,如果他们选择单元格,则只会选择该单个单元格。

因此,对于第三个要求,我将SelectionMode 设置为CellSelect。对于列选择,我选择了列中的所有单元格,但是当我尝试打印 SelectedColumns 时,它打印为零。看来我也必须选择列标题。我不知道如何以编程方式选择列标题。所需的代码如下。谁能告诉我如何做到这一点?

private void dataGridViewFileData_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{
    dataGridViewFileData.MultiSelect = true;
    dataGridViewFileData.SelectionMode = DataGridViewSelectionMode.CellSelect;
    for (int i = 0; i < dataGridViewFileData.Rows.Count; ++i)
         dataGridViewFileData.Rows[i].Cells[0].Selected = true;
    MessageBox.Show("Selected columns:" + dataGridViewFileData.SelectedColumns.Count.ToString());
}

【问题讨论】:

    标签: c# .net winforms datagridview


    【解决方案1】:

    作为一个选项,您可以将SelectionMode 设置为CellSelect,然后处理CellClick 并针对单击的单元格的行索引和列索引并选择该单元格,或整行或整列或全部使用代码的单元格。

    由于选择模式为CellSelect,因此选定的列或选定的行为空,如果出于任何原因要跟踪选定的列或选定的行,则需要手动跟踪。

    对于选择的视觉反馈也是如此,您需要设置标题的背景颜色或自己绘制它们。例如:

    private async void Form1_Load(object sender, EventArgs e)
    {
        dataGridView1.ColumnCount = 3;
        dataGridView1.RowCount = 3;
        dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;
        dataGridView1.CellClick += DataGridView1_CellClick;
        dataGridView1.EnableHeadersVisualStyles = false;
    }
    DataGridViewColumn selectedColumn = null;
    DataGridViewRow selectedRow = null;
    List<DataGridViewCell> selectedCells = null;
    private void DataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
    {
        dataGridView1.ClearSelection();
    
        if (selectedColumn != null)
            selectedColumn.HeaderCell.Style.BackColor =
                dataGridView1.ColumnHeadersDefaultCellStyle.BackColor;
        if (selectedRow != null)
            selectedRow.HeaderCell.Style.BackColor =
                dataGridView1.RowHeadersDefaultCellStyle.BackColor;
    
        selectedColumn = null;
        selectedRow = null;
        selectedCells = null;
        if (e.ColumnIndex == -1 && e.RowIndex == -1)
        {
            dataGridView1.SelectAll();
            selectedCells = new List<DataGridViewCell>();
            foreach (DataGridViewRow row in dataGridView1.Rows)
                selectedCells.AddRange(row.Cells.Cast<DataGridViewCell>());
        }
        else if (e.ColumnIndex == -1 && e.RowIndex > -1)
        {
            selectedRow = dataGridView1.Rows[e.RowIndex];
            foreach (DataGridViewCell cell in dataGridView1.Rows[e.RowIndex].Cells)
                cell.Selected = true;
        }
        else if (e.ColumnIndex > -1 && e.RowIndex == -1)
        {
            selectedColumn = dataGridView1.Columns[e.ColumnIndex];
            foreach (DataGridViewRow row in dataGridView1.Rows)
                row.Cells[e.ColumnIndex].Selected = true;
        }
        else
        {
            selectedCells = selectedCells = new List<DataGridViewCell>()
                { dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex] };
            dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected = true;
        }
        if (selectedColumn != null)
            selectedColumn.HeaderCell.Style.BackColor = SystemColors.Highlight;
        if (selectedRow != null)
            selectedRow.HeaderCell.Style.BackColor = SystemColors.Highlight;
    }
    

    【讨论】:

    • 您的代码也不会选择 columnheader 或 rowheader 。因为那些的索引是-1。您的代码没有处理这种情况。这是我必须处理的具体情况。
    • 明显选中的列或者选中的行是空的,因为选择方式是CellSelect
    • 如果我选择一列中的所有单元格,那么它不会是列选择。因此选定的列数必须为一。
    • 您正在使用DataGridView,并且选定的列不同于选择列的所有单元格。但是,您可以将单击的列索引/单击的行索引保留在变量中。
    • 问题是另一个函数根据 selectedcolumns.count 删除选定的多个列。而且我必须直观地显示选定的列。
    【解决方案2】:

    作为另一个选项,您可以处理OnCellMouseDown 事件,并根据单击的单元格决定设置SelectionMode。这样就可以得到视觉反馈以及SelectedColumnsSelectedRows

    private void Form1_Load(object sender, EventArgs e)
    {
        dataGridView1.ColumnCount = 3;
        dataGridView1.RowCount = 3;
        foreach (DataGridViewColumn c in dataGridView1.Columns)
            c.SortMode = DataGridViewColumnSortMode.NotSortable;
        dataGridView1.CellMouseDown += DataGridView1_CellMouseDown;
    }
    private void DataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
    {
        dataGridView1.ClearSelection();
        if (e.ColumnIndex == -1 && e.RowIndex == -1)
        {
            dataGridView1.SelectionMode = DataGridViewSelectionMode.ColumnHeaderSelect;
            dataGridView1.SelectAll();
        }
        else if (e.ColumnIndex == -1 && e.RowIndex > -1)
        {
            dataGridView1.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect;
            dataGridView1.Rows[e.RowIndex].Selected = true;
        }
        else if (e.ColumnIndex > -1 && e.RowIndex == -1)
        {
            dataGridView1.SelectionMode = DataGridViewSelectionMode.ColumnHeaderSelect;
            dataGridView1.Columns[e.ColumnIndex].Selected = true;
        }
        else
        {
            dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;
            dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected = true;
        }
    }
    

    【讨论】:

    • 我也喜欢这个选项,也许更喜欢它。试一试或查看屏幕截图,让我知道您的反馈。
    猜你喜欢
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    • 2013-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多