【问题标题】:WPF DataGrid ScrollIntoView doesn't scroll to requested rowWPF DataGrid ScrollIntoView 不会滚动到请求的行
【发布时间】:2019-03-02 16:41:26
【问题描述】:

我正在使用大约 50 行的 WPF DataGrid。我正在使用 MVVM 模式。 用户可以在一行中搜索一些文本,datagrid 应该突出显示该行(不一定选择该行),如果该行在屏幕上尚不可见,则滚动到该行。

修整的 XAML 代码:

<DataGrid ItemsSource="{Binding MyDataView,Mode=TwoWay}" Name="myDataGrid"
          AutoGeneratingColumn="Generate_Column" 
          CurrentCell="{Binding DGCurrentCell, Mode=OneWayToSource}" SelectedItem="{Binding SelectedRow, Mode=TwoWay}"
          HorizontalScrollBarVisibility="Disabled" VirtualizingPanel.ScrollUnit="Item"
          VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingStackPanel.IsVirtualizing="False"
          IsSynchronizedWithCurrentItem="True">

代码背后:

public void ScrollToItem(object gridObj, object item)
{
    myDataGrid.Dispatcher.BeginInvoke((Action)(() =>
    {
        myDataGrid.Focus();
        myDataGrid.UpdateLayout();
        myDataGrid.ScrollIntoView(item);
    }));
}

视图模型:

    protected override bool FindItem(string searchString)
    {
        bool itemFound=false;
        DataRow[] rows = this.MyDataTable.Select(searchString);
        if (rows.Count() > 0)
        {
            itemFound = true;
            //Scroll to the first row which is a match
            (this.View as SCDataGridView).ScrollToItem(this, rows[0]);
        }
        return itemFound;
    }

如果找到项目,则调用 ScrollToItem API,但 scrollviewer 永远不会滚动到该项目。 我尝试了以下字段的各种组合,但到目前为止没有任何帮助:

HorizontalScrollBarVisibility- Auto or Disabled
VirtualizingPanel.ScrollUnit- Pixel or Item
VirtualizingStackPanel.VirtualizationMode- Standard or Recycling
VirtualizingStackPanel.IsVirtualizing - True or False

我错过了什么?

谢谢,

RDV

【问题讨论】:

    标签: wpf datagrid scrollview


    【解决方案1】:

    在我的类似版本中查找和强制数据网格滚动到位置的方式略有不同...轻微,但仍然不同。

    public void ScrollToItem(object gridObj, object item)
    {
        myDataGrid.Dispatcher.BeginInvoke( DispatcherPriority.Normal, (Action)(() =>
        {
            myDataGrid.UpdateLayout();
            myDataGrid.ScrollIntoView(item, null);
            SelectedRow = item;
        }));
    }
    

    【讨论】:

      【解决方案2】:

      我发现了为什么ScrollIntoView 对我不起作用的问题。 ScrollIntoView 需要绑定到 ItemsSource 的确切对象类型。在我的例子中,ItemsSource 绑定到 MyDataView,并且每个项目都是 DataRowView 类型。当调用ScrollIntoView 时,我正在传递 DataRow 对象,因此它不起作用。

      一旦我传递了正确的 DataRowView 对象,它就起作用了。我不必将 SelectedItem 设置为此项目(因为我不想选择该项目,只需滚动到搜索的项目)。 以下是工作示例 - 我不必调用 UpdateLayout() 或 beginInvoke

      public void ScrollToItem(object gridObj, int itemIdx)
      {
          myDataGrid.ScrollIntoView((this.DataContext).MyDataView[itemIdx], null);
      }
      

      我在调试时意识到的另一件重要的事情是,要在 DataGrid/List 等上打开或关闭虚拟化,应该使用 ScrollViewer.CanScrollContent 而不是 VirtualizingPanel.ScrollUnit 属性,因为 ScrollViewer.CanScrollContent 被传递给实际上是滚动查看器负责实施虚拟化。

      同样,ScrollViewer.CanScrollContent 的真/假值对ScrollIntoView 的功能没有影响。

      希望这对某人有所帮助。

      RDV

      【讨论】:

        猜你喜欢
        • 2019-03-17
        • 2013-08-03
        • 2012-03-28
        • 2013-06-21
        • 2022-10-18
        • 2017-07-12
        • 1970-01-01
        • 2011-02-18
        • 2016-04-12
        相关资源
        最近更新 更多