ListBoxItem.Parent 不返回任何内容,也无法通过 VisualTreeHelper.GetParent 获取它

Shi*_*mmy 5 wpf xaml listbox listboxitem visual-tree

如何提取 ListBoxItem 的父容器?在下面的例子中,我可以去到 ListBoxItem,比它更高,我什么都没有:

<ListBox Name="lbAddress">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <Button Click="Button_Click"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>
Run Code Online (Sandbox Code Playgroud)
Private Sub Button_Click(sender As Button, e As RoutedEventArgs)
  Dim lbAddress = GetAncestor(Of ListBox) 'Result: Nothing
End Sub
Run Code Online (Sandbox Code Playgroud)
Public Shared Function GetAncestor(Of T)(reference As DependencyObject) As T
  Dim parent = GetParent(reference)

  While parent IsNot Nothing AndAlso Not parent.GetType.Equals(GetType(T))
    parent = GetAncestor(Of T)(parent)
  End While

  If parent IsNot Nothing Then _
    Return If(parent.GetType Is GetType(T), parent, Nothing) 

  Return Nothing    
End Sub

Public Function GetParent(reference As DependencyObject) As DependencyObject
  Dim parent As DependencyObject = Nothing

 If TypeOf reference Is FrameworkElement Then
    parent = DirectCast(reference, FrameworkElement).Parent
  ElseIf TypeOf reference Is FrameworkContentElement Then
    parent = DirectCast(reference, FrameworkContentElement).Parent
  End If

  Return If(parent, VisualTreeHelper.GetParent(reference))
End Function
Run Code Online (Sandbox Code Playgroud)

更新

这就是发生的情况(注意“父”变量保持为空):

这是它的样子

Ray*_*rns 4

很明显,lbAddress.ItemsSource在单击按钮期间,有东西正在删除项目。问题是,什么?仔细看看您发布的图片就会找到答案。这是您代码中的错误:

My.Context.DeleteObject(context)
My.Context.SaveChanges()

   ...

btn.GetVisualAncestor(...)
Run Code Online (Sandbox Code Playgroud)

前两行更新您的数据模型。这会立即从可视化树中删除 ListBoxItem。当您稍后调用 GetVisualAncestor 来查找 ListBox 时,它会失败,因为 ListBoxItem 不再具有任何类型的父项。

我确信解决方案现在对您来说是显而易见的:只需在从数据模型中删除数据之前找到 ListBox 祖先,然后就可以开始了。