WPF DataGrid ScrollIntoView不会滚动到请求的行

时间:2018-09-26 20:27:19

标签: wpf datagrid scrollview

我正在使用具有约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);
    }));
}

ViewModel:

    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;
    }

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

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

我想念什么?

谢谢

RDV

2 个答案:

答案 0 :(得分:0)

在我具有相似版本的查找方式和强制datagrid滚动到位置方面有细微的区别...次要,但仍然有所不同。

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

答案 1 :(得分:0)

我发现了一个问题,为什么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