So I have this code:

<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>

It defines some properties for tree view item, but it doesn't work entirely - I mean it sets foreground colors, but when I double click any item, it doesn't fire my command.

有帮助吗?

解决方案

I take it this is related to your previous question.

  • With this setup you have that I mentioned yesterday, remember the RelayCommand<T> needs to be on the concerned element not the parent VM. That's why you're probably seeing the Foreground properties work fine but not the Command getting executed since the DataContext where the command is being looked for(ServerItem and DatabaseItem) does not actually define the Commands ConnectServer and ConnectDb.
  • Also instead of having two triggers, set ConnectDb as default and use the trigger to set ConnectServer for just ServerItem's on the concerned elements.

Now to fix your problem you can define ConnectServer command in your ServerItem and ConnectDb command in your DatabaseItem, or if you want to keep the commands in the DataContext of the TreeView, use a RelativeSource binding to find these commands from the TreeView.

something like (Tested this and it works fine):

<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>

Update: (Fix for the recursive DoubleClick event call of TreeViewItem's)

In your class MouseDoubleClick

switch:

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);
  }
}

to

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);
  }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top