Question

J'ai un TreeView typique et un viewmodel. Le viewmodel a une collection observable d'autres viewmodels qui sert de source de données pour l'arbre.

public class TreeViewVM {
    public ObservableCollection<ItemVM> Items { get; private set; }
    public ItemVM SelectedItem { get; set; }
}

et ItemVM:

public class ItemVM {
    public string Name { get; set; }
    public ImageSource Image { get; private set; }
    public ObservableCollection<ItemVM> Children { get; private set; }
    public ICommand Rename { get; private set; }
}

La vue:

<TreeView Selecteditem="{Binding SelectedItem}" ItemsSource="{Binding Items}">
    <TreeView.ItemTemplate>
         <HierarchicalDataTemplate>
             <StackPanel Orientation="Horizontal">
                 <StackPanel.InputBindings>
                     <KeyBinding Key="F2" Command="{Binding Rename}"/>
                 </StackPanel.InputBindings>
                 <Image Source="{Binding Image}"/>
                 <TextBlock Text="{Binding Name}"/>
         </HierarchicalDataTemplate>
      </TreeView.ItemTemplate>
  </TreeView>

Cependant ma commande ne sera pas invoqué, peu importe ce que j'essaie aussi longtemps qu'il est « dans » l'HierarchicalDataTemplate.

Si je déplace le KeyBinding dans les TreeView.InputBindings (et le ICommand / RelayCommand du ItemVM au TreeViewVM) tout est agréable, la commande s'invoquée.

Mais je voudrais avoir la commande sur le ItemVM (comme il est là où il est logique). Toutes les idées?

Était-ce utile?

La solution

La clé de liaison serait nécessaire de définir le TreeViewItem, comme c'est l'élément avec la mise au point. Le problème est que vous ne pouvez pas définir des raccourcis clavier à l'aide d'un style, qui est ce que vous auriez probablement envie de faire ici.

est une solution de contournement qui utilise une propriété attachée personnalisée pour ajouter des éléments à la collection de InputBinding via un style. Donc, vous voudriez utiliser quelque chose comme ça pour définir votre style, que vous souhaitez affecter à TreeView.ItemContainerStyle.

Autres conseils

  

Mais je voudrais avoir la commande sur le ItemVM (comme il est là où il est logique). Toutes les idées?

Si TreeViewVM suit l'élément sélectionné dans la propriété SelectedItem vous pouvez définir InputBindings sur TreeView et ont encore les commandes mises en œuvre sur le ItemVM:

<TreeView ItemsSource="{Binding Items}">
  <TreeView.InputBindings>
    <KeyBinding Key="F2" Command="{Binding SelectedItem.Rename}"/>
  </TreeView.InputBindings>
</TreeView>

Remarquez comment la syntaxe est utilisée SelectedItem.Rename sous-propriété d'utiliser la ItemVM comme source de la liaison.

Malheureusement, il est un peu fastidieux de se lier à l'élément sélectionné sur un TreeView. Vous ne pouvez pas lier directement à SelectedItem (comme XAML semble suggérer) mais il existe diverses méthodes pour surmonter cette limitation .

Une méthode simple consiste à utiliser Mélange Interactivité :

<TreeView Name="treeView" ItemsSource="{Binding Items}">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectedItemChanged">
      <i:InvokeCommandAction Command="{Binding SetSelectedItemCommand}" CommandParameter="{Binding SelectedItem, ElementName=treeView}" />
    </i:EventTrigger>
  </i:Interaction.Triggers>
</TreeView>

Vous devrez mettre en œuvre un SetSeletectedItemCommand sur TreeViewVM qui définit la SelectedItem propriété.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top