c# - DataGridView 滚动点击后跳转到顶部

标签 c# .net winforms mvvm datagridview

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

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

唯一的另一个问题是我使用带有数据绑定(bind)的 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;
}

最佳答案

这里有两个问题:

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

  • 如果将 2 和 2 放在一起,您会发现数据网格不是在调整滚动时而是在尝试单击该行时反弹的。众所周知,重新绑定(bind) datagridview 会将滚动重置回顶部。

    我的解决方案是在重新绑定(bind) 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();
            }
        }
    }
    

    Functionally, this shouldn't differ from something like txtPartNumberQuery_OnChanged(){RebindGrid();}



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

    关于c# - DataGridView 滚动点击后跳转到顶部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29569484/

    相关文章:

    c# - 如何获取两个地理坐标之间的所有点

    c# - 获取堆栈跟踪

    c# - 传递上下文对象的替代方法

    c# - 我想要一个单例的设计替代方案

    c# - 从 C# 运行 Jar 文件

    c# - 为什么我的 GridSplitter 没有出现?

    c# - 无法使用 "Precompile during publishing"选项部署网站

    c# - Windows窗体旋转

    c# - 将保存按钮绑定(bind)到 DataTable

    c# - 在其他控件上方显示具有半透明背景颜色的标签?