【问题标题】:DataGridView selectionChanged event firing multiple timesDataGridView selectionChanged 事件多次触发
【发布时间】:2014-04-10 05:14:23
【问题描述】:

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

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

请告知是否可以获取所选数据键(主键) DataGridView 记录。 DataGridView 会根据主键绑定吗 ?

编辑

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

但 DataGridView1_SelectionChanged 事件会触发多次。

【问题讨论】:

  • 我建议您为主键字段添加另一列并通过 dgv.CurrentRow.Cells["colPKField"].Value 检索它。
  • 但我被要求不要在 GridView 中显示主键。我认为它也不安全..!你说什么?
  • 您可以通过将 visible 属性分配为 false 来隐藏该列。 dgv.Columns["colPKField"].Visible =false;
  • @Nimesh 是的,我实现了它,它运行良好。但是当我调用 dgv_SelectionChanged 事件时,我遇到了严重的问题,它被多次触发。我发现 SOF 中的其他一些人也遇到了异常,但没有解释他是如何解决的。
  • 试试RowEnter事件。

标签: c# winforms data-binding datagridview selectionchanged


【解决方案1】:

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

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

【讨论】:

  • 崇高敬意!这个问题在 Win Forms 中很常见,您有最简单的解决方案!你能解释一下这个属性是做什么的吗? MSDN 文档不够清晰。
  • 非常感谢,你救了我的命 ;-)
  • 对那些无与伦比的 winforms 挫败感之一的伟大解决方案。
【解决方案2】:

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

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

希望对你有帮助

【讨论】:

    【解决方案3】:

    我已经尝试过 RowEnter 事件,但它对我来说很好。你如何检查它?使用消息框或在事件中放置断点。因为,断点和消息框将失去所选行的焦点。然后,当您在消息框或断点之后继续时,网格将重新获得焦点,事件将再次执行。

    尝试以下步骤来检查事件执行情况。

    处理多次执行。

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

    【讨论】:

    • 我也试过RowEnter。但它会发射多次。当表单加载时,甚至当我点击网格的外侧(空白区域)时它被触发,所以选定的行索引值为 0。
    • 那么您可以通过将最后选择的行索引存储在任何变量中来避免多次执行。
    【解决方案4】:

    如果重置数据绑定,您可以收到一个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();
    
        // ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-17
      • 2014-03-26
      • 2011-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多