Связывание клавиш на TreeViewItem - PullRequest
8 голосов
/ 29 июня 2010

У меня типичная древовидная структура и модель представления.Модель представления имеет наблюдаемую коллекцию других моделей представления, которая служит источником данных для дерева.

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

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

Представление:

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

Однако моя команда не будет вызываться, независимо от того, что я пробую, пока онанаходится "внутри" HierarchicalDataTemplate.

Если переместить связывание клавиш в TreeView.InputBindings (и ICommand / RelayCommand из ItemVM в TreeViewVM), все будет хорошо, команда будет вызвана.

Но я хотел бы иметь команду на ItemVM (так как именно там, где это имеет смысл).Есть идеи?

Ответы [ 2 ]

8 голосов
/ 23 января 2013

Но я хотел бы иметь команду на ItemVM (так, как там, где это имеет смысл). Есть идеи?

Если TreeViewVM отслеживает выбранный элемент с помощью свойства SelectedItem, вы можете задать InputBindings для TreeView, и при этом команды ItemVM:

будут реализованы
<TreeView ItemsSource="{Binding Items}">
  <TreeView.InputBindings>
    <KeyBinding Key="F2" Command="{Binding SelectedItem.Rename}"/>
  </TreeView.InputBindings>
</TreeView>

Обратите внимание, как используется синтаксис субпредложения SelectedItem.Rename для использования ItemVM в качестве источника привязки.

К сожалению, привязка к выбранному элементу на TreeView немного утомительна. Вы не можете напрямую связываться с SelectedItem (как, по-видимому, ваш XAML), но существует различных способов преодолеть это ограничение . Один простой способ, который мне нравится, это использовать Blend Interactivity :

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

Вам нужно будет реализовать SetSeletectedItemCommand для TreeViewVM, который устанавливает свойство SelectedItem.

6 голосов
/ 09 марта 2011

Связывание ключа должно быть определено в TreeViewItem, так как это элемент с фокусом. Проблема в том, что вы не можете определить привязки клавиш с помощью стиля, что вы, вероятно, хотели бы сделать здесь.

Здесь - это один из обходных путей, который использует пользовательское присоединенное свойство для добавления элементов в коллекцию InputBinding с помощью стиля. Таким образом, вы захотите использовать что-то подобное для определения своего стиля, который вы назначите TreeView.ItemContainerStyle.

...