Ugh, sorry, I may have misled earlier. I didn't see anywhere in the code in the MS post actually seemed to get the TreeViewItem, it was getting the VirtualizingStackPanel and bringing it into view and (if I'm remembering) selected the TreeViewItem. Also, I've not yet looked up the difference in them all, but that code uses CType and TryCast instead of DirectCast.
Hauling bricks for more yard work this morning (amazing how a little yard work fixes my programming problems face-palm) it dawned on me that the item I'm looking for is now in view! AFTER calling the BringInfoView routine I can now just use ItemContainerGenerator.ContainerFromIndex to get the item the user was searching for selected!
So, to recap, keeping in mind that I am NOT dealing with child items, if you have the index of the item you want, call the BringIntoView (which calls FindVisualChild) like this, which then allows you to get a reference to the TreeViewItem and select it:
'TView is the tree you're working with, i is the index
Call BringIntoView(TView, i)
'Now that bring into view made it visible you can get the TreeViewItem and select it
TVItm = TView.ItemContainerGenerator.ContainerFromIndex(i)
TVItm.IsSelected = True
The Sub and Function:
Private Function FindVisualChild(Of T As System.Windows.Media.Visual)(ByVal visual As System.Windows.Media.Visual) As T
For i As Integer = 0 To VisualTreeHelper.GetChildrenCount(visual) - 1
Dim child As System.Windows.Media.Visual = CType(VisualTreeHelper.GetChild(visual, i), System.Windows.Media.Visual)
If child IsNot Nothing Then
Dim correctlyTyped As T = TryCast(child, T)
If correctlyTyped IsNot Nothing Then
Return correctlyTyped
End If
Dim descendent As T = FindVisualChild(Of T)(child)
If descendent IsNot Nothing Then
Return descendent
End If
End If
Next
Return Nothing
End Function
Sub BringIntoView(TheTreeView As TreeView, TheIdx As Integer)
Try
Dim parent As ItemsControl = TryCast(TheTreeView, ItemsControl)
If parent IsNot Nothing Then
Dim itemHost As System.Windows.Controls.VirtualizingStackPanel = FindVisualChild(Of System.Windows.Controls.VirtualizingStackPanel)(parent)
If itemHost IsNot Nothing Then
itemHost.BringIndexIntoViewPublic(TheIdx)
End If
End If
Catch ex As Exception
MsgBox("Error in BringIntoView: " & ex.Message & vbCrLf & "TheIdx: " & TheIdx)
End Try
End Sub
On another note while I have your ear, Peter. I've added this TreeView.ItemContainerStyle to the TreeView XAML and an IsExp property to the FontSetData class so that when I change the items in the TreeView I can have the ones that were expanded stay expanded when the refresh happens.
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExp, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</Style>
</TreeView.ItemContainerStyle>
Becuase the FntData doesn't have this IsExp property I'm seeing a bunch of errors saying BindingExpression path error: 'IsExp' property not found on 'object' ''FntData', which makes sense.
My question is what's the best practice to handle that? Do I simply add that property to the FntData class or is there a way to exclude it in the XAML?
Thank you again, Peter!