Domanda

Ho un controllo TreeView tipico e un ViewModel. Il ViewModel ha una collezione di altri osservabile ViewModels che serve come fonte di dati per l'albero.

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

e l'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; }
}

Il punto di vista:

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

Tuttavia il mio comando non viene invocato, non importa quello che cerco fintanto che è "dentro" il HierarchicalDataTemplate.

Se mi muovo il KeyBinding nelle TreeView.InputBindings (e ICommand / RelayCommand dal ItemVM alla TreeViewVM) tutto è bello, il comando viene invocato.

Ma mi piacerebbe avere il comando sul ItemVM (come è dove ha senso). Tutte le idee?

È stato utile?

Soluzione

La chiave di associazione avrebbe bisogno di essere definito sulla TreeViewItem, in quanto è l'elemento con la messa a fuoco. Il problema è che non è possibile definire combinazioni di tasti con uno stile, che è quello che si sarebbe probabilmente vuole fare qui.

Qui è una soluzione che utilizza una proprietà personalizzata collegata per aggiungere elementi alla collezione InputBinding tramite uno stile. Quindi, che ci si vuole usare qualcosa di simile per definire il tuo stile, che si sarebbe assegnato a TreeView.ItemContainerStyle.

Altri suggerimenti

  

Ma mi piacerebbe avere il comando sul ItemVM (come è dove ha senso). Tutte le idee?

Se TreeViewVM tiene traccia della voce selezionata tramite la proprietà SelectedItem è possibile definire InputBindings su TreeView e hanno ancora i comandi implementati sulla ItemVM:

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

Si noti come la sintassi SelectedItem.Rename sottoproprietà è impiegato per utilizzare la ItemVM come la fonte del legame.

Purtroppo, è un po 'noiosa di legarsi alla voce selezionata su una TreeView. Non è possibile si legano direttamente al SelectedItem (come XAML sembra suggerire), ma esistono vari metodi per superare questa limitazione .

Un metodo semplice è quello di utilizzare Frullare interattività :

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

Si dovrà attuare un SetSeletectedItemCommand su TreeViewVM che imposta la SelectedItem proprietà.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top