2

这很奇怪。下面代码的重点是支持 attachProperty,如果容器的任何子项已获得焦点,它将通知容器。

即,我在其内容中的某处有一个带有文本框的网格,如果其中一个控件获得焦点,我想将网格变为蓝色。

我有一个带有 ItemsTemplate 的 ListView。ItemsTemplate 是一个 DataTemplate,其中包含一些东西……但其中之一是 ContentControl。

例子:

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

ContentControl 上的 Binding 应该显示某种类型的 UserControl。创建后...工作得很好。如果我从 Grid 元素开始递归迭代 listViewItem 的模板......它也会遍历 ContentControl 的“内容”。

但是...一旦我对 ListView ItemsSource 绑定到的 ObservableCollection 执行 .Move(),根据 LogicalTreeHelper,ContentControl.Content 为空。

是什么赋予了?

如果我检查 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);
  }
}
4

1 回答 1

0

阿罗哈,

以下是如何解决问题的建议:

我不确定 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 属性是什么。

于 2013-03-09T00:04:23.147 回答