LogicalTreeHelper.GetChildren - ObservableCollection Move()导

本文关键字:Move ObservableCollection GetChildren LogicalTreeHelper | 更新日期: 2023-09-27 18:03:06

这很奇怪。下面代码的要点是支持attachedProperty,当容器的任何子容器都收到焦点时,attachedProperty会通知容器。

。我有一个网格,在它的内容中有一个文本框,如果其中一个控件得到焦点,我想把网格变成蓝色。

我有一个ListView与ItemsTemplate。ItemsTemplate是一个包含一些东西的数据模板…但其中一个是ContentControl

的例子:

<ListView>
   <ListView.ItemTemplate>
      <DataTemplate>
         <Grid>
           <Border>
            <ContentControl Content="{Binding Something}"/>
           </Border>
         </Grid>
      </DataTemplate>
   </ListView.ItemTemplate>
</ListView>

ContentControl上的Binding应该显示某种类型的UserControl。在创建…工作得很好。如果我递归地迭代listViewItem从Grid元素开始的模板…它也会遍历ContentControl的"Content"

然而

…一旦我在ListView ItemsSource绑定到的ObservableCollection上做了. move (), ContentControl。根据LogicalTreeHelper,内容为空。

给了什么?

如果我检查ContentControl,它会显示内容…但LogicalTreeHelper。GetChildren返回一个空的枚举数。

我困惑…

谁能解释一下为什么会这样?

LogicalTreeHelper迭代器方法

public static void applyFocusNotificationToChildren(DependencyObject parent)
{
  var children = LogicalTreeHelper.GetChildren(parent);
  foreach (var child in children)
  {
    var frameworkElement = child as FrameworkElement;
    if (frameworkElement == null)
      continue;
    Type frameworkType = frameworkElement.GetType();
    if (frameworkType == typeof(TextBox) || frameworkType == typeof(ListView) ||
      frameworkType == typeof(ListBox) || frameworkType == typeof(ItemsControl) ||
      frameworkType == typeof(ComboBox) || frameworkType == typeof(CheckBox))
    {
      frameworkElement.GotFocus -= frameworkElement_GotFocus;
      frameworkElement.GotFocus += frameworkElement_GotFocus;
      frameworkElement.LostFocus -= frameworkElement_LostFocus;
      frameworkElement.LostFocus += frameworkElement_LostFocus;
      // If the child's name is set for search
    }
    applyFocusNotificationToChildren(child as DependencyObject);
  }
}

LogicalTreeHelper.GetChildren - ObservableCollection Move()导

再见,

这是一个如何解决你的问题的建议:

我不确定我是否拼写正确的GotFocus事件,但它是一个RoutedEvent,你可以在你的视觉树的任何地方使用它。

如果你的一个项目收到一个焦点,你的ListView将得到通知,并在处理程序中你可以做任何你想做的。

这个怎么样:

<ListView GotFocus="OnGotFocus">
   <ListView.ItemTemplate>
      <DataTemplate>
         <Grid>
           <Border>
            <ContentControl Content="{Binding Something}"/>
           </Border>
         </Grid>
      </DataTemplate>
   </ListView.ItemTemplate>
</ListView>

这只是一些随机的逻辑来演示你可以做什么。

public void OnGotFocus(object sender, RoutedEventArgs e)
{
  TreeViewItem item = sender as TreeViewItem;
  if(((MyViewModel)item.Content).SomeColor == "Blue")
  {
    Grid g = VisualTreeHelper.GetChild(item, 0) as Grid;
    g.Background = Colors.Blue;
  }
}

GotFocus是一个RoutedEvent,如果被触发,它将在可视树中冒泡。所以在某处捕获事件并检查哪个是触发事件的原始源对象。或者检查触发事件的对象的ViewModel属性。