Imports System.Windows.Interactivity
Imports System.Collections.Specialized
Public Class ScrollIntoViewForListBox
Inherits Behavior(Of ListBox)
Private ItemsSource As INotifyCollectionChanged
Private ListControl As ListBox
'''
''' When Beahvior is attached
'''
Protected Overrides Sub OnAttached()
MyBase.OnAttached()
ListControl = Me.AssociatedObject
AddHandler Me.AssociatedObject.SelectionChanged, AddressOf AssociatedObject_SelectionChanged
End Sub
Private Sub AssociatedObject_CollectionChanged(sender As Object, e As System.Collections.Specialized.NotifyCollectionChangedEventArgs)
If IsNothing(ItemsSource) Then
Dim CurrItemsSource As IEnumerable = Me.AssociatedObject.ItemsSource
ItemsSource = TryCast(CurrItemsSource, INotifyCollectionChanged)
AddHandler ItemsSource.CollectionChanged, AddressOf AssociatedObject_CollectionChanged
RemoveHandler Me.AssociatedObject.SelectionChanged, AddressOf AssociatedObject_SelectionChanged
' SE SI CAMBIA ITEMSSOURCE PERDE IL RIFERIMENTO E SMETTE DI FUNZIONARE
' PER RIATTIVARLO USARE IL SEGUENTE CODICE COMMENTATO
'ElseIf ItemsSource IsNot Me.AssociatedObject.ItemsSource Then
' Dim PreviousItemsSourceList As INotifyCollectionChanged = TryCast(ItemsSource, INotifyCollectionChanged)
' RemoveHandler PreviousItemsSourceList.CollectionChanged, AddressOf AssociatedObject_CollectionChanged
' Dim CurrItemsSource As IEnumerable = Me.AssociatedObject.ItemsSource
' ItemsSource = TryCast(CurrItemsSource, INotifyCollectionChanged)
' AddHandler ItemsSource.CollectionChanged, AddressOf AssociatedObject_CollectionChanged
End If
End Sub
'''
''' On Selection Changed
'''
'''
'''
Private Sub AssociatedObject_SelectionChanged(sender As Object, e As SelectionChangedEventArgs)
If ListControl.SelectedItem IsNot Nothing Then
Dim SelectedItemIndex As Integer = ListControl.Items.IndexOf(ListControl.SelectedItem)
ListControl.Dispatcher.BeginInvoke(DirectCast(Sub()
ListControl.UpdateLayout()
If ListControl.SelectedItem IsNot Nothing Then
ListControl.ScrollIntoView(ListControl.SelectedItem)
End If
End Sub, Action))
If SelectedItemIndex > 0 Then
ListControl.Dispatcher.BeginInvoke(DirectCast(Sub()
ListControl.UpdateLayout()
ListControl.ScrollIntoView(ListControl.Items(SelectedItemIndex - 1))
End Sub, Action))
End If
If SelectedItemIndex < ListControl.Items.Count - 2 Then
ListControl.Dispatcher.BeginInvoke(DirectCast(Sub()
ListControl.UpdateLayout()
ListControl.ScrollIntoView(ListControl.Items(SelectedItemIndex + 1))
End Sub, Action))
End If
End If
End Sub
'''
''' When behavior is detached
'''
Protected Overrides Sub OnDetaching()
MyBase.OnDetaching()
'RemoveHandler Me.AssociatedObject.SelectionChanged, AddressOf AssociatedObject_SelectionChanged
RemoveHandler ItemsSource.CollectionChanged, AddressOf AssociatedObject_CollectionChanged
End Sub
End Class
Public Class ScrollIntoViewForDataGrid
Inherits Behavior(Of DataGrid)
Private ItemsSource As INotifyCollectionChanged
Private DataGridControl As DataGrid
'''
''' When Beahvior is attached
'''
Protected Overrides Sub OnAttached()
MyBase.OnAttached()
DataGridControl = Me.AssociatedObject
AddHandler Me.AssociatedObject.SelectionChanged, AddressOf AssociatedObject_SelectionChanged
End Sub
Private Sub AssociatedObject_CollectionChanged(sender As Object, e As System.Collections.Specialized.NotifyCollectionChangedEventArgs)
UpdateSelectedItemPosition()
End Sub
'''
''' On Selection Changed
'''
'''
'''
Private Sub AssociatedObject_SelectionChanged(sender As Object, e As SelectionChangedEventArgs)
If IsNothing(ItemsSource) Then
Dim CurrItemsSource As IEnumerable = Me.AssociatedObject.ItemsSource
ItemsSource = TryCast(CurrItemsSource, INotifyCollectionChanged)
AddHandler ItemsSource.CollectionChanged, AddressOf AssociatedObject_CollectionChanged
'SE SI CAMBIA ITEMSSOURCE PERDE IL RIFERIMENTO E SMETTE DI FUNZIONARE
'PER RIATTIVARLO USARE IL SEGUENTE CODICE COMMENTATO
ElseIf Not IsNothing(Me.AssociatedObject.ItemsSource) AndAlso ItemsSource IsNot Me.AssociatedObject.ItemsSource Then
Dim PreviousItemsSourceList As INotifyCollectionChanged = TryCast(ItemsSource, INotifyCollectionChanged)
RemoveHandler PreviousItemsSourceList.CollectionChanged, AddressOf AssociatedObject_CollectionChanged
Dim CurrItemsSource As IEnumerable = Me.AssociatedObject.ItemsSource
ItemsSource = TryCast(CurrItemsSource, INotifyCollectionChanged)
AddHandler ItemsSource.CollectionChanged, AddressOf AssociatedObject_CollectionChanged
Else
UpdateSelectedItemPosition()
End If
End Sub
Private Sub UpdateSelectedItemPosition()
If DataGridControl.SelectedItem IsNot Nothing Then
Dim SelectedItemIndex As Integer = DataGridControl.Items.IndexOf(DataGridControl.SelectedItem)
DataGridControl.Dispatcher.BeginInvoke(DirectCast(Sub()
DataGridControl.UpdateLayout()
If DataGridControl.SelectedItem IsNot Nothing Then
DataGridControl.ScrollIntoView(DataGridControl.SelectedItem)
End If
End Sub, Action))
If SelectedItemIndex > 0 Then
DataGridControl.Dispatcher.BeginInvoke(DirectCast(Sub()
DataGridControl.UpdateLayout()
DataGridControl.ScrollIntoView(DataGridControl.Items(SelectedItemIndex - 1))
End Sub, Action))
End If
If SelectedItemIndex < DataGridControl.Items.Count - 2 Then
DataGridControl.Dispatcher.BeginInvoke(DirectCast(Sub()
DataGridControl.UpdateLayout()
DataGridControl.ScrollIntoView(DataGridControl.Items(SelectedItemIndex + 1))
End Sub, Action))
End If
End If
End Sub
'''
''' When behavior is detached
'''
Protected Overrides Sub OnDetaching()
MyBase.OnDetaching()
RemoveHandler Me.AssociatedObject.SelectionChanged, AddressOf AssociatedObject_SelectionChanged
RemoveHandler ItemsSource.CollectionChanged, AddressOf AssociatedObject_CollectionChanged
End Sub
End Class