我正在使用具有约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
答案 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