WPF DataGrid过滤了项目,跳转滚动条

时间:2016-01-05 19:20:13

标签: c# wpf xaml datagrid

我有一个'open the glossary document Using document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True) Dim wbPart As WorkbookPart = document.WorkbookPart If wbPart Is Nothing Then Console.WriteLine("can't find workbook") End If ' Find the correct worksheet, given its name. Dim sheet = _ wbPart.Workbook.Descendants(Of Sheet)(). _ Where(Function(s) s.Name = worksheetName).FirstOrDefault If sheet Is Nothing Then Console.WriteLine(worksheetName & " sheet does not exist") End If Dim worksheetPart As WorksheetPart = CType(wbPart.GetPartById(sheet.Id), WorksheetPart) ' In the worksheet, retrieve a collection of rows where the ' row index matches the row you're trying to delete. Although you ' know there's only one such row, the Descendants method returns ' a collection. Dim rowindex As Integer Dim theSheet As Sheet = wbPart.Workbook.Descendants(Of Sheet)().Where(Function(s) s.Name = worksheetName).FirstOrDefault() Dim wsPart As WorksheetPart = CType(wbPart.GetPartById(theSheet.Id), WorksheetPart) Dim rows = wsPart.Worksheet.Descendants(Of Row)() Dim bolDelete As Boolean For rowindex = intGlossaryStartRow To rows.Count bolDelete = True 'PrintBR("Processing row: " & rowindex.ToString) For Each lst As Integer In glossaryRowList If rowindex = lst Then bolDelete = False End If Next If bolDelete Then 'PrintBR("Deleting row: " & rowindex.ToString) Dim deletingRow = _ worksheetPart.Worksheet.Descendants(Of Row)(). _ Where(Function(r) r.RowIndex.Value = rowindex).FirstOrDefault() If deletingRow Is Nothing Then ' The specified row does not exist. 'PrintBR("ROW " & rowindex.ToString & " is nothing! [[[[[[[[[[[[ ABORT ]]]]]]]]]]]]]") 'Return End If Try deletingRow.Remove() 'deletingRow.Hidden = True Catch ex As Exception End Try Else 'this row collection is in the GlossaryRowList Dim keepingRow = _ worksheetPart.Worksheet.Descendants(Of Row)(). _ Where(Function(r) r.RowIndex.Value = rowindex).FirstOrDefault() 'get the index of the rowindex value in GlossaryRowList Dim listIndex As Integer = glossaryRowList.IndexOf(rowindex) 'try to insert the keepingRow at row listIndex Try sheet.InsertAt(keepingRow, intGlossaryStartRow + listIndex) Catch ex As Exception End Try End If Next ' Save the worksheet part. worksheetPart.Worksheet.Save() End Using ,其中DataGrid填充了控件。我还使用过滤器/查询机制来过滤控件的内容。

当未过滤数据网格时,滚动工作正常。但是,当我过滤(=将项目的可见性设置为false,这会折叠数据网格中的项目)时,滚动变得非常“jump”。当我向下滚动时,滚动条变得越来越小,滚动变成了烦人的体验。

我阅读了有关virtualization的内容,以及有关设置DataGrid.ScrollViewer的内容,但我在XAML中没有这些属性。

为什么感觉微不足道的东西如此过于复杂......无论如何,我如何配置我的数据网格:

  • 通过数据绑定显示项目列表
  • 能够过滤列表(通过折叠项目)
  • 并且显然有一个滚动条允许用户滚动而不会感到沮丧:)

我的XAML:

ItemSource

许多人提前感谢。

PS:非常感谢一些额外的解释,实际上从中学到一些东西是一个很好的奖励...

1 个答案:

答案 0 :(得分:2)

DataGrid有一个ViewPort,只会渲染和计算实际显示的内容。这被称为虚拟化。根据行/单元数据的视觉变化将不可避免地导致“跳跃”,因为DataGrid将在现场计算它们。

Scrollviewer上的设置,以及将网格置于Scrollviewer内,将禁用虚拟化。这意味着整个网格将立即渲染:

  • 网格可以流畅滚动
  • 网格的初始加载时间将更长:当网格上附加了太多数据时,它将变得无法使用。

如果您的网格只包含有限数量的行,则可能没问题。

解决此问题的更好方法是直接过滤ItemsSource。使用ObservableCollection并在那里过滤您的数据。网格将显示与ObservableCollection一致的行。

这很简单,您使用此RowStyle重建的行为设置了Visibility。