1
votes

I am trying to implement excel like feature in DataGridView. So:

  1. if they select column header it would select the column
  2. if the user selects row header then entire row would be selected
  3. Apart from this if they select cell, only that single cell would be selected.

To so so, for the third requirement I made the SelectionMode as CellSelect. For a column selection I selected all the cells in a column , but when I tried to print SelectedColumns, it printed as zero. It seems I have to select the column headers also. I don't know how to select column header programmatically. The required code is below. Can anybody tell me how to achieve this?

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());
}
2

2 Answers

3
votes

As an option you can set the SelectionMode to CellSelect, then handle the CellClick and regarding to the row index and column index of the clicked cell and select the cell, or full row or full column or all cells using code.

Since the selection mode is CellSelect, selected columns or selected rows are empty and if for any reason you want to track selected column or selected row, you need to track it manually.

The same for visual feedback about the selection, you need to set back color of the headers or paint them yourself. For example:

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;
}

enter image description here

0
votes

As another option you can handle OnCellMouseDown event and depending to the clicked cell, decide to set SelectionMode. This way, you can get the visual feedback as well as SelectedColumns and SelectedRows:

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;
    }
}

enter image description here