Прикрепленные свойства на TreeViews

Итак, у меня есть этот код:

<Style TargetType="{x:Type TreeViewItem}">
    <Style.Resources>
        <Converters:GetElementTypeConverter x:Key="GetElementTypeConverter" />
    </Style.Resources>
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=., Converter={StaticResource GetElementTypeConverter}}" Value="{x:Type Models:ServerItem}">
            <Setter Property="CommandBehaviors:MouseDoubleClick.Command" Value="{Binding ConnectServer}" />
            <Setter Property="CommandBehaviors:MouseDoubleClick.CommandParameter" Value="{Binding Path=SelectedItem, RelativeSource={RelativeSource Self}}" />
            <Setter Property="Foreground" Value="Gray" />
        </DataTrigger>
        <DataTrigger Binding="{Binding Path=., Converter={StaticResource GetElementTypeConverter}}" Value="{x:Type Models:DatabaseItem}">
            <Setter Property="CommandBehaviors:MouseDoubleClick.Command" Value="{Binding ConnectDb}" />
            <Setter Property="CommandBehaviors:MouseDoubleClick.CommandParameter" Value="{Binding Path=SelectedItem, RelativeSource={RelativeSource Self}}" />
            <Setter Property="Foreground" Value="Red" />
        </DataTrigger>
    </Style.Triggers>
</Style>

Он определяет некоторые свойства для элемента в виде дерева, но он не работает полностью - я имею в виду, что он устанавливает цвета переднего плана, но когда я дважды щелкаю по любому элементу, он не запускает мою команду.

1 ответ

Решение

Я так понимаю, это связано с вашим предыдущим вопросом.

  • С этой настройкой у вас есть то, что я упоминал вчера, помните RelayCommand<T> должен находиться на соответствующем элементе, а не на родительской виртуальной машине. Вот почему вы, вероятно, видите Foreground свойства работают нормально, но команда не выполняется, так как DataContext где команда ищет (ServerItem а также DatabaseItem) на самом деле не определяет команды ConnectServer а также ConnectDb,
  • Кроме того, вместо двух триггеров, установите ConnectDb по умолчанию и используйте триггер, чтобы установить ConnectServer Просто для ServerItemна соответствующие элементы.

Теперь, чтобы исправить вашу проблему, вы можете определить ConnectServer командовать в вашем ServerItem а также ConnectDb командовать в вашем DatabaseItemили если вы хотите сохранить команды в DataContext TreeView, использовать RelativeSource привязка, чтобы найти эти команды из TreeView,

что-то вроде (проверено это и работает нормально):

<TreeView ItemsSource="{Binding ServerItems}">
  <TreeView.ItemContainerStyle>
    <Style TargetType="{x:Type TreeViewItem}">
      <Style.Resources>
        <CommandBehaviors:GetElementTypeConverter x:Key="GetElementTypeConverter" />
      </Style.Resources>
      <Setter Property="CommandBehaviors:MouseDoubleClick.Command"
              Value="{Binding Path=DataContext.ConnectDb,
                              RelativeSource={RelativeSource FindAncestor,
                                                              AncestorType={x:Type TreeView}}}" />
      <Setter Property="CommandBehaviors:MouseDoubleClick.CommandParameter"
              Value="{Binding Path=.}" />
      <Setter Property="Foreground"
              Value="Black" />
      <Style.Triggers>
        <DataTrigger Binding="{Binding Path=.,
                                        Converter={StaticResource GetElementTypeConverter}}"
                      Value="{x:Type CommandBehaviors:ServerItem}">
          <Setter Property="CommandBehaviors:MouseDoubleClick.Command"
                  Value="{Binding Path=DataContext.ConnectServer,
                                  RelativeSource={RelativeSource FindAncestor,
                                                                  AncestorType={x:Type TreeView}}}" />
          <Setter Property="Foreground"
                  Value="Tomato" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </TreeView.ItemContainerStyle>
  <TreeView.ItemTemplate>
    <HierarchicalDataTemplate ItemsSource="{Binding Databases}">
      <TextBlock Text="{Binding}" />
    </HierarchicalDataTemplate>
  </TreeView.ItemTemplate>
</TreeView>

Обновление: (Исправлено для рекурсивного DoubleClick вызов события TreeViewItem"S)

В вашем классе MouseDoubleClick

переключатель:

public class MouseDoubleClick {

  ...

  private static void OnMouseDoubleClick(object sender, RoutedEventArgs e) {
    Control control = sender as Control;
    ICommand command = (ICommand)control.GetValue(CommandProperty);
    object commandParameter = control.GetValue(CommandParameterProperty);
    command.Execute(commandParameter);
  }
}

в

public class MouseDoubleClick {

  ...

  private static void OnMouseDoubleClick(object sender, RoutedEventArgs e) {
    Control control = sender as Control;
    var possibleTreeViewItem = sender as TreeViewItem;
    if (control == null || (possibleTreeViewItem != null && !possibleTreeViewItem.IsSelected))
      return;
    ICommand command = (ICommand)control.GetValue(CommandProperty);
    object commandParameter = control.GetValue(CommandParameterProperty);
    command.Execute(commandParameter);
  }
}
Другие вопросы по тегам