2010-06-29 6 views
7

J'ai une arborescence typique et un viewmodel. Le modèle de vue possède une collection observable d'autres modèles de vue qui sert de source de données pour l'arbre.KeyBinding sur un TreeViewItem

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 TreeView.InputBindings (et ICommand/RelayCommand de ItemVM vers TreeViewVM) tout est sympa, la commande est invoquée.

Mais je voudrais avoir la commande sur le ItemVM (car c'est là où c'est logique). Des idées?

Répondre

5

La liaison de clé doit être définie sur TreeViewItem, car il s'agit de l'élément avec le focus. Le problème est que vous ne pouvez pas définir de raccourcis clavier à l'aide d'un style, ce que vous voudrez probablement faire ici.

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

7

Mais je voudrais avoir la commande sur le ItemVM (car c'est là où cela a du sens). Des idées?

Si TreeViewVM pistes l'élément sélectionné par la SelectedItem propriété que 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 de sous-propriété SelectedItem.Rename est utilisée pour utiliser la ItemVM comme source de la liaison.

Malheureusement, il est légèrement fastidieux de lier à l'élément sélectionné sur un TreeView. Vous ne pouvez pas lier directement à SelectedItem (comme votre XAML semble suggérer) mais il existe various methods to overcome this limitation. Une méthode simple que j'aime est d'utiliser Blend Interativity:

<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 propriété SelectedItem.

+0

Bon, merci! –

+0

Cela a fonctionné très bien pour moi. Merci de signaler ** SelectedItem **. Renommer. –

+0

@MartinLiversage, s'il vous plaît, voir ma question http://stackoverflow.com/questions/36865204/keybinding-in-hierarchicaldatatemplate-of-treeview – StepUp

Questions connexes