DataGridView selectionChanged事件多次触发

时间:2014-04-10 05:14:24

标签: c# winforms data-binding datagridview selectionchanged

在我的应用程序中,我使用DataGridView来显示列表。当用户在datagridview中选择一条记录时,它应该在另一个面板中显示详细信息。为了进行选择,我被要求使用DataGridView1_SelectionChanged事件。

DataGridView应该只包含一列,但详细信息显示可能包含所选记录的更多信息(我们可以通过查询所选的主键值来获取数据库中的所有详细信息)。

  

请告知是否可以获取所选的数据密钥(主键)   DataGridView记录。 DataGridView是否将基于主键进行绑定   ?

修改

我已经实现了DataGridView1.Columns [" ID"]。Visible = false。它运作良好。 为了选择,我添加了DataGridView1_SelectionChanged事件。

  

但DataGridView1_SelectionChanged事件多次触发。

4 个答案:

答案 0 :(得分:20)

在执行代码之前,您可以在selectionchanged事件中使用DataGrid.focused属性:

private void dg_SelectionChanged(object sender, EventArgs e)
    {
        if (dg.Focused)
        {
            // your code
        }
    } 

答案 1 :(得分:2)

我今天遇到了同样的问题,经过数小时的实验,我找到了解决方案,或者更确切地说是解决这个问题的方法

this.dgvSearchResult.SelectionChanged -= dgvSearchResult_SelectionChanged;
this.onSearch();
this.dgvSearchResult.SelectionChanged += new EventHandler(dgvSearchResult_SelectionChanged);

希望它有所帮助

答案 2 :(得分:1)

我尝试过RowEnter事件,但它适用于我。你怎么检查它?使用消息框或在事件中放置断点。因为,断点和消息框将从所选行中取消焦点。然后,当您在消息框或断点之后继续时,网格将重新聚焦并且事件将再次执行。

尝试以下步骤检查事件执行情况。 enter image description here

处理多次执行。

int LastRowIndex =-1;

private void dgv_RowEnter(...)
{
    if (LastRowIndex != e.RowIndex)
    {
        //Place your code here.
    }
    LastRowIndex = e.RowIndex;
}

答案 3 :(得分:0)

如果重置了数据绑定,则可以获取一个SelectionChanged来通知列表暂时为空,然后在填充数据后再通知另一个。更糟糕的是,自重置之前,所选项目甚至可能没有更改。我通过在每次通话中检查SelectedCells来验证了这一点。

一种解决方案是使用无效变量,然后检入Application.Idle事件。这对分组更改和避免不必要的更新具有很好的效果。消息泵为空时,Application.Idle将立即运行,因此用户不会注意到延迟。最好是在网格整理完毕后检查是否甚至需要更改。

您需要在构造函数中设置静态表单实例属性。

private bool isViewUpToDate = false;

private void DataGrid_SelectionChanged(object sender, EventArgs e) => isViewUpToDate = false;

public void CheckDataGridSelectionView()
{
    if (isViewUpToDate)
        return;

    // Logic goes here

    isViewUpToDate = true;
}

static void Main()
{
    Application.Idle += (sender, eventData) => MainForm.Instance?.CheckDataGridSelectionView();

    // ...
}