在鼠标单击时保持多选并执行更多功能

时间:2017-10-05 23:21:45

标签: c# .net winforms datagridview

您好我正在使用C#进行申请。

我想要实现的目标

  • 我在 DataGridView
  • 中的结果中选择 CTRL 的多行
  • 然后我右键单击它并显示选项
  • 我点击选择选项
  • 选择的行保留在 DataGridView 上,其他行已删除

我遇到问题的问题

  • 我选择 CTRL
  • 的多行
  • 但是,当我右键单击行时,多项选择消失

注意:我正在使用MouseClick事件右键单击行并生成菜单。这个事件的代码如下:

private void SearchPanelDataGridView_MouseClick(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        ContextMenuStrip smenu = new System.Windows.Forms.ContextMenuStrip();
        var htest = SearchPanelDataGridView.HitTest(e.X, e.Y);
        SearchPanelDataGridView.ClearSelection();
        SearchPanelDataGridView.Rows[htest.RowIndex].Selected = true;

        smenu.Items.Add("Clear Record").Name = "Clear Record";
        smenu.Items.Add("Pay Amount").Name = "Pay Amount";
        smenu.Items.Add("Break Apart").Name = "Break Apart";
        smenu.Items.Add("View Details").Name = "View Details";
        smenu.Items.Add("Choose Selected").Name = "Choose Selected"; // Choose Rows Option
        smenu.Items.Add("Reset").Name = "Reset";

        int CurrentMouseOverRow = SearchPanelDataGridView.HitTest(e.X, e.Y).RowIndex;
        smenu.Show(SearchPanelDataGridView, new Point(e.X, e.Y));
        smenu.ItemClicked += new ToolStripItemClickedEventHandler(smenu_ItemClicked);
    }
}

3 个答案:

答案 0 :(得分:1)

您无需处理MouseClick事件。只需使用设计器或表单的加载事件创建ContextmenuStrip即可。然后将上下文菜单条分配给ContextMenuStrip的{​​{1}}属性,然后处理DataGridView的{​​{1}}事件,该事件应删除未选择的行并使用此类代码:

Click

这样,所有未选择的行都将被删除,选择将保持不变。

答案 1 :(得分:1)

似乎很难完全避免这种行为,但是您可以使用以下变通方法,并在DataGridView取消选择它们后恢复选定的行:

private bool SUSPEND_EVENT_HANDLING;
private List<DataGridViewRow> dgvMyGridSelectedRows = new List<DataGridViewRow>();

private void dgvMyGrid_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
    dgvMyGridSelectedRows.Clear();

    // if the mouse is down on a selected row then remember all selected rows
    if (dgvMyGrid.Rows(e.RowIndex).Selected)
        dgvMyGridSelectedRows.AddRange(dgvMyGrid.SelectedRows.Cast<DataGridViewRow>);
}

private void dgvMyGrid_SelectionChanged(object sender, EventArgs e)
{
    if (!IsHandleCreated || SUSPEND_EVENT_HANDLING)
        return;

    // restore the remembered rows selection
    if (dgvMyGridSelectedRows.Any())
    {
        SUSPEND_EVENT_HANDLING = true;
        dgvMyGrid.ClearSelection();
        dgvMyGridSelectedRows.ForEach(x => x.Selected = true);
        SUSPEND_EVENT_HANDLING = false;
    }
}

SUSPEND_EVENT_HANDLING是为了避免堆栈溢出,因为您在SelectionChanged事件处理程序中选择了行。

答案 2 :(得分:0)

这可能不是最好的解决方案,但现在你可以试试这个:

    List<int> selectedRowsIndexes = new List<int>();
    private void dataGridView1_Click(object sender, EventArgs e)
    {
        selectedRowsIndexes.Clear();
        foreach (DataGridViewRow row in dataGridView1.SelectedRows)
           selectedRowsIndexes.Add(row.Index);
    }

    private void dataGridView1_MouseClick(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            ContextMenuStrip smenu = new System.Windows.Forms.ContextMenuStrip();
            var htest = dataGridView1.HitTest(e.X, e.Y);
            dataGridView1.ClearSelection();
            dataGridView1.Rows[htest.RowIndex].Selected = true;

            smenu.Items.Add("Clear Record").Name = "Clear Record";
            smenu.Items.Add("Pay Amount").Name = "Pay Amount";
            smenu.Items.Add("Break Apart").Name = "Break Apart";
            smenu.Items.Add("View Details").Name = "View Details";
            smenu.Items.Add("Choose Selected").Name = "Choose Selected"; // Choose Rows Option
            smenu.Items.Add("Reset").Name = "Reset";

            int CurrentMouseOverRow = dataGridView1.HitTest(e.X, e.Y).RowIndex;
            smenu.Show(dataGridView1, new Point(e.X, e.Y));

            foreach (int rowIndex in selectedRowsIndexes)
            {
                for (int i = 0; i < dataGridView1.Rows.Count; i++)
                {
                   dataGridView1.Rows[i].Selected = (i == rowIndex);
                }
            }
        }
    }

为此,DataGridView的SelectionMode属性应设置为FullRowSelect。