2

これは非常に奇妙です。以下のコードのポイントは、コンテナーの子のいずれかがフォーカスを受け取った場合にコンテナーに通知する attachedProperty をサポートすることです。

つまり、コンテンツのどこかに textBox を持つグリッドがあり、それらのコントロールの 1 つがフォーカスされた場合にグリッドを青に変えたいとします。

ItemsTemplate を持つ ListView があります。ItemsTemplate は、いくつかのものを含む DataTemplate ですが、そのうちの 1 つは 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 は Enumerator を返し、空の状態にします。

よくわかりません...

なぜこれが当てはまるのか、誰でも説明できますか?

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であり、ビジュアルツリーのどこでも使用できます。

アイテムの1つがフォーカスを受け取ると、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 に答える