滚动WPF DataGrid以显示所选项目在顶部

前端之家收集整理的这篇文章主要介绍了滚动WPF DataGrid以显示所选项目在顶部前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个DataGrid与许多项目,我需要以编程方式滚动到SelectedItem.我在StackOverflow和Google上搜索,似乎解决方案是ScrollIntoView,如下所示:
  1. grid.ScrollIntoView(grid.SelectedItem)

它会向上或向下滚动DataGrid,直到所选项目对焦.但是,根据当前相对于所选项目的滚动位置,所选项可能最终成为DataGrid的ScrollViewer中最后一个可见项.我希望所选项目将是ScrollViewer中的第一个可见项目(假设DataGrid中有足够的行可以允许).所以我试过这个:

  1. 'FindVisualChild is a custom extension method that searches in the visual tree and returns
  2. 'the first element of the specified type
  3. Dim sv = grid.FindVisualChild(Of ScrollViewer)
  4. If sv IsNot Nothing Then sv.ScrollToEnd()
  5. grid.ScrollIntoView(grid.SelectedItem)

首先,我滚动到DataGrid的末尾,然后滚动到SelectedItem,此时SelectedItem显示在DataGrid的顶部.

我的问题是滚动到DataGrid的结尾很好,但随后滚动到所选项目并不总是奏效.

如何解决这个问题,还有其他替代策略可以滚动到顶部位置的特定记录?

你在正确的轨道上,只是尝试使用集合视图,而不是直接在datagrid上工作,以满足这种需求.

这是一个工作示例,其中所需项目总是作为第一选择项目显示,否则滚动浏览器将滚动到最后,并在其位置选择目标项目.

要点是:

>在业务端使用CollectionView,并启用XAML控件上的当前项同步(IsSynchronizedWithCurrentItem = true)
>延迟“真实”目标滚动,以便允许“可选”执行“选择最后一个项目”(通过使用低优先级的Dispatcher.BeginInvoke)

这是业务逻辑(这是从C#到VB的自动转换)

  1. Public Class Foo
  2.  
  3. Public Property FooNumber As Integer
  4. Get
  5. End Get
  6. Set
  7. End Set
  8. End Property
  9. End Class
  10.  
  11. Public Class MainWindow
  12. Inherits Window
  13. Implements INotifyPropertyChanged
  14.  
  15. Private _myCollectionView As ICollectionView
  16.  
  17. Public Sub New()
  18. MyBase.New
  19. DataContext = Me
  20. InitializeComponent
  21. MyCollection = New ObservableCollection(Of Foo)
  22. MyCollectionView = CollectionViewSource.GetDefaultView(MyCollection)
  23. Dim i As Integer = 0
  24. Do While (i < 50)
  25. MyCollection.Add(New Foo)
  26. i = (i + 1)
  27. Loop
  28.  
  29. End Sub
  30.  
  31. Public Property MyCollectionView As ICollectionView
  32. Get
  33. Return Me._myCollectionView
  34. End Get
  35. Set
  36. Me._myCollectionView = value
  37. Me.OnPropertyChanged("MyCollectionView")
  38. End Set
  39. End Property
  40.  
  41. Private Property MyCollection As ObservableCollection(Of Foo)
  42. Get
  43. End Get
  44. Set
  45. End Set
  46. End Property
  47.  
  48. Private Sub ButtonBase_OnClick(ByVal sender As Object,ByVal e As RoutedEventArgs)
  49. Dim targetNum As Integer = Convert.ToInt32(targetScroll.Text)
  50. Dim targetObj As Foo = Me.MyCollection.FirstOrDefault(() => { },(r.FooNumber = targetNum))
  51.  
  52. 'THIS IS WHERE THE MAGIC HAPPENS
  53. If (Not (targetObj) Is Nothing) Then
  54. 'Move to the collection view to the last item
  55. Me.MyCollectionView.MoveCurrentToLast
  56. 'Bring this last item into the view
  57. Dim current = Me.MyCollectionView.CurrentItem
  58. itemsContainer.ScrollIntoView(current)
  59. 'This is the trick : Invoking the real target item select with a low priority allows prevIoUs visual change (scroll to the last item) to be executed
  60. Dispatcher.BeginInvoke(DispatcherPriority.ContextIdle,New Action(() => { },Me.ScrollToTarget(targetObj)))
  61. End If
  62.  
  63. End Sub
  64.  
  65. Private Sub ScrollToTarget(ByVal targetObj As Foo)
  66. Me.MyCollectionView.MoveCurrentTo(targetObj)
  67. itemsContainer.ScrollIntoView(targetObj)
  68. End Sub
  69.  
  70. Public Event PropertyChanged As PropertyChangedEventHandler
  71.  
  72. Protected Overridable Sub OnPropertyChanged(ByVal propertyName As String)
  73. If (Not (PropertyChanged) Is Nothing) Then
  74. PropertyChanged?.Invoke(Me,New PropertyChangedEventArgs(propertyName))
  75. End If
  76.  
  77. End Sub
  78. End Class

这是xaml

  1. <Grid>
  2. <Grid.ColumnDefinitions>
  3. <ColumnDefinition/>
  4. <ColumnDefinition/>
  5. </Grid.ColumnDefinitions>
  6. <DataGrid x:Name="itemsContainer" ItemsSource="{Binding MyCollectionView}" IsSynchronizedWithCurrentItem="True" Margin="2" AutoGenerateColumns="False" >
  7. <DataGrid.Columns>
  8. <DataGridTextColumn Binding="{Binding FooNumber}"></DataGridTextColumn>
  9. </DataGrid.Columns>
  10. </DataGrid>
  11.  
  12. <StackPanel Grid.Column="1">
  13. <TextBox x:Name="targetScroll" Text="2" Margin="2"></TextBox>
  14. <Button Content="Scroll To item" Click="ButtonBase_OnClick" Margin="2"></Button>
  15. </StackPanel>
  16. </Grid>

猜你在找的VB相关文章