我已经使用附加到 TreeView 的行为解决了这个问题。TreeViewItems 或模板似乎没有将命令路由到它们。幸运的是,TreeView 还有一个 SelectedItem 属性,可以用来获取 ViewModel!
(行为在概念上类似于@Natxo 答案中链接中的解决方案,但它并不能解决所有问题。)
行为类:
public class TreeViewClipboardBehavior : Behavior<TreeView>
{
protected override void OnAttached()
{
base.OnAttached();
CommandBinding CopyCommandBinding = new CommandBinding(
ApplicationCommands.Copy,
CopyCommandExecuted,
CopyCommandCanExecute);
AssociatedObject.CommandBindings.Add(CopyCommandBinding);
CommandBinding CutCommandBinding = new CommandBinding(
ApplicationCommands.Cut,
CutCommandExecuted,
CutCommandCanExecute);
AssociatedObject.CommandBindings.Add(CutCommandBinding);
CommandBinding PasteCommandBinding = new CommandBinding(
ApplicationCommands.Paste,
PasteCommandExecuted,
PasteCommandCanExecute);
AssociatedObject.CommandBindings.Add(PasteCommandBinding);
}
private void CopyCommandExecuted(object target, ExecutedRoutedEventArgs e)
{
NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
if (item != null && item.CanCopyToClipboard)
{
item.CopyToClipboard();
e.Handled = true;
}
}
private void CopyCommandCanExecute(object target, CanExecuteRoutedEventArgs e)
{
NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
if (item != null)
{
e.CanExecute = item.CanCopyToClipboard;
e.Handled = true;
}
}
private void CutCommandExecuted(object target, ExecutedRoutedEventArgs e)
{
NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
if (item != null && item.CanCutToClipboard)
{
item.CutToClipboard();
e.Handled = true;
}
}
private void CutCommandCanExecute(object target, CanExecuteRoutedEventArgs e)
{
NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
if (item != null)
{
e.CanExecute = item.CanCutToClipboard;
e.Handled = true;
}
}
private void PasteCommandExecuted(object target, ExecutedRoutedEventArgs e)
{
NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
if (item != null && item.CanPasteFromClipboard)
{
item.PasteFromClipboard();
e.Handled = true;
}
}
private void PasteCommandCanExecute(object target, CanExecuteRoutedEventArgs e)
{
NestingItemTreeViewModelBase item = AssociatedObject.SelectedItem as NestingItemTreeViewModelBase;
if (item != null)
{
e.CanExecute = item.CanPasteFromClipboard;
e.Handled = true;
}
}
}
XAML
<TreeView Grid.Row="2" ItemsSource="{Binding SystemTreeRoot}">
<i:Interaction.Behaviors>
<local:TreeViewClipboardBehavior/>
</i:Interaction.Behaviors>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:MyViewModel}" ItemsSource="{Binding Children}">
<!-- Template content -->
</HierarchicalDataTemplate>
</TreeView>