2010-06-29 13 views
7

Mam typowy widok drzewa i viewmodel. Viewmodel ma możliwą do zaobserwowania kolekcję innych modeli wyświetlania, które służą jako źródło danych dla drzewa.KeyBinding na TreeViewItem

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

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

Widok:

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

Jednak moje polecenie nie zostanie wywołany bez względu na to, co staram tak długo, jak to jest "wewnątrz" HierarchicalDataTemplate .

Jeśli przeniesię KeyBinding w TreeView.InputBindings (i ICommand/RelayCommand z ItemVM na TreeViewVM) wszystko jest w porządku, polecenie zostanie wywołane.

Ale chciałbym mieć polecenie na ItemVM (ponieważ jest tam, gdzie ma sens). Jakieś pomysły?

Odpowiedz

5

Kluczowe powiązanie należy zdefiniować na TreeViewItem, ponieważ jest to element z fokusem. Problem polega na tym, że nie możesz definiować powiązań klawiszy za pomocą stylu, co prawdopodobnie chciałbyś tutaj zrobić.

Here to jedno obejście, które wykorzystuje niestandardową właściwość dołączaną do dodawania elementów do kolekcji InputBinding za pośrednictwem stylu. Więc chcesz użyć czegoś takiego, aby zdefiniować swój styl, który przypiszesz do TreeView.ItemContainerStyle.

7

Ale chciałbym mieć polecenie na ItemVM (tak, jak to ma sens). Jakieś pomysły?

Jeśli TreeViewVM śledzi wybrany przedmiot za pośrednictwem właściwości SelectedItem można zdefiniować InputBindings na TreeView i jeszcze polecenia realizowane na ItemVM:

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

zauważyć, jak składnia podwłasnością SelectedItem.Rename jest zatrudniony używać ItemVM jako źródło powiązania.

Niestety, jest nieco uciążliwe, aby powiązać z wybranym elementem na TreeView. Nie można powiązać bezpośrednio z SelectedItem (jak wydaje się sugerować twój XAML), ale istnieje various methods to overcome this limitation. Jedna prosta metoda lubię jest użycie 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> 

Trzeba będzie zaimplementować SetSeletectedItemCommand na TreeViewVM który ustawia właściwość SelectedItem.

+0

Dobra, dziękuję! –

+0

To zadziałało dla mnie świetnie. Dziękuję za wskazanie ** SelectedItem **. Rename. –

+0

@MartinLiversage, proszę, zobacz moje pytanie http://stackoverflow.com/questions/36865204/keybinding-in-hierarchicaldatatemplate-of-treeview – StepUp