滚动并单击后,DataGridView跳转到顶部

时间:2015-04-10 19:40:11

标签: c# .net winforms mvvm datagridview

我有一个带过滤的DataGridView。应用过滤器后,滚动位置将返回到顶部,并且网格中的数据将按预期更新。当我然后使用滚动条向下滚动然后单击一行时,滚动会再次跳回到顶部并且选择了错误的行。然后我再次向下滚动并单击,不重置。这是我期望的行为。

我理解为什么第一次跳跃发生是因为网格已经有效地反弹到新的来源。但是,为什么它在滚动和点击后再次跳起来有点令人烦恼。我尝试过使用BindingList和BindingSource。我已经尝试在DataGridView上调用各种更新和刷新以及位置重置,以尝试以编程方式而不是在用户单击时引发第二次重置。有什么想法吗?

唯一的另一个问题是我正在使用带有数据绑定的MVVM模式来近似我们在网络上使用的knockout.js。在功能上,这应该与txtPartNumberQuery_OnChanged(){RebindGrid();}

等不同

在我花时间写这篇文章之后我就把它想出来了,所以...我想我会回答我自己的问题。

查看型号:

public string PartQueryString { 
    get
    {
        return _partQueryString;
    } 
    set
    {
        _partQueryString = value;
        //observe this value and trigger a search when it changes
        this.PartMaster.DataSource = _model.SearchPartMaster(_partQueryString);
    }
}

查看:

private void ConfigureGridView()
{
    gvPartMaster.AutoGenerateColumns = false;            
    gvPartMaster.Columns.Add(Common.Helper.GetBasicGridViewColumn<DataGridViewTextBoxColumn>("Number", "Part Number"));
    gvPartMaster.Columns.Add(Common.Helper.GetBasicGridViewColumn<DataGridViewTextBoxColumn>("Description", "Part Description" ));
    gvPartMaster.Columns.Add(Common.Helper.GetBasicGridViewColumn<DataGridViewTextBoxColumn>("ManufacturerDescription", "Manufacturer" ));
    gvPartMaster.Columns.Add(Common.Helper.GetBasicGridViewColumn<DataGridViewTextBoxColumn>("CategoryDescription", "Category" ));
    gvPartMaster.Columns.Add(Common.Helper.GetBasicGridViewColumn<DataGridViewTextBoxColumn>("Specs", "Specs"));
    gvPartMaster.ColumnHeadersDefaultCellStyle.WrapMode = DataGridViewTriState.False;

    gvPartMaster.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
}

private void ApplyBindings()
{
    txtPartNumberQuery.DataBindings.Add("Text", _viewModel, "PartQueryString", false, DataSourceUpdateMode.OnPropertyChanged);
    gvPartMaster.DataSource = _viewModel.PartMaster;
}

1 个答案:

答案 0 :(得分:0)

这里有两个问题:

  • 文本框上的数据绑定会在失去焦点时触发一段额外的时间,即使该值没有真正改变。
  • 单击滚动条不会导致失去焦点。

如果你将2和2放在一起,你会得到数据网格反弹,而不是当他们调整滚动但是当他们试图点击该行时。众所周知,重新绑定datagridview会将滚动重置为顶部。

我的解决方案是在重新绑定gridview之前确保过滤条件已更改。

public string PartQueryString { 
    get
    {
        return _partQueryString;
    } 
    set
    {
        if (_partQueryString != value)
        {
            _partQueryString = value;
            //observe this value and trigger a search when it changes
            this.PartMaster.DataSource = _model.SearchPartMaster(_partQueryString);
            _view.UpdateGridViewPosition();
        }
    }
}
  

从功能上讲,这不应该与txtPartNumberQuery_OnChanged(){RebindGrid();}

等不同

这实际上是一个很糟糕的假设,因为TextChanged事件不会像数据绑定那样被触发两次。