我有一个TreeView。我想通过单击 F2 来启用EditLeafCommand

型号:

public class Leaf
{
    public string LeafName { get; set; }
    public bool HasChildren { get; set; }
}

窗口的ViewModel:
public MainWindowViewModel{

  public ReadOnlyCollection<LeafViewModel> Leafs
  {
        get { return leafs; }
  }
}

TreeView的 ViewModel:
public class LeafViewModel : TreeViewItemViewModel
{
    public ObservableCollection<TreeViewItemViewModel> Children
    {
        get { return _children; }
    }
    public string LeafName { get; set; }
    public RelayCommand EditLeafCommand { get; set; }

}

XAML:
<TreeView  ItemsSource="{Binding Leafs}">
   <TreeView.InputBindings>
      <KeyBinding Key="F2" Command="{Binding SelectedItem.EditLeafCommand,
                           diag:PresentationTraceSources.TraceLevel=High}"/>
   </TreeView.InputBindings>
   <TreeView.Resources>
      <HierarchicalDataTemplate DataType="{x:Type vm:LeafViewModel}"
                                     ItemsSource="{Binding Children}">
         <StackPanel Orientation="Horizontal">
            <TextBox Text="{Binding LeafName}" IsReadOnly="{Binding IsReadOnlyItem}"
            Tag="{Binding DataContext, RelativeSource={RelativeSource Self}}">
               <TextBox.ContextMenu>
                  <ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
                     <MenuItem Command="{Binding EditLeafCommand}" CommandParameter="{Binding ALeaf}" Header="Edit" />
                  </ContextMenu>
               </TextBox.ContextMenu>
            </TextBox>
         </StackPanel>
      </HierarchicalDataTemplate>
   </TreeView.Resources>
</TreeView>

输出窗口:



我看到了这篇文章和it is it is the same question,但是,接受的答案没有任何代码(我尝试通过链接,但是,提供的方法对我没有帮助)

错误提示:



但是,我如何直接指向EditLeadViewModel呢?

如何从EditLeafCommand调用LeafViewModel并发送参数?

最佳答案

您的MainViewModel没有SelectedItem属性。您需要将此属性添加到 View 模型中,并确保当该属性更改时触发INotifyPropertyChanged.PropertyChanged事件。

每当树形 View 的所选项目更改时,您还需要更新此属性。有多种方法可以做到这一点。一种方法是使用Nuget包System.Windows.Interactivity.WPF。您将必须添加一个 namespace 声明:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

然后,在树形 View XAML元素内添加以下内容(我仅显示要添加的内容-将其余XAML保留在TreeView元素内):
<TreeView Name="treeView" ItemsSource="{Binding Leafs}">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectedItemChanged">
      <i:InvokeCommandAction Command="{Binding SetSelectedItemCommand, PresentationTraceSources.TraceLevel=High}" CommandParameter="{Binding SelectedItem, ElementName=treeView}" />
    </i:EventTrigger>
  </i:Interaction.Triggers>
</TreeView>

请注意,TreeView元素具有一个名称(treeView),该名称用于CommandParameter元素中的InvokeCommandAction绑定(bind)中。

另外,请注意,您必须在SetSelectedItemCommand上添加MainViewModel。此命令应设置我在第一段中描述的SelectedItem属性。这是一些使用通用 RelayCommand 的代码片段:
class MainWindowViewModel {

  TreeViewItemViewModel selectedItem;

  public MainWindowViewModel() {
    SetSelectedItemCommand = new RelayCommand<TreeViewItemViewModel>(SetSelectedItem);
  }

  public TreeViewItemViewModel SelectedItem {
    get { return selectedItem; }
    set {
      selectedItem = value;
      OnPropertyChanged();
    }
  }

  void SetSelectedItem(TreeViewItemViewModel viewModel) {
    SelectedItem = viewModel;
  }

}

这是使您的SelectedItem.EditLeafCommand key 绑定(bind)正常工作所需的基本内容。但是,您还有另一个问题。您的HierarchicalDataTemplate将树节点定义为TextBox。当您单击TextBox时,没有点击冒泡到TreeView,并且选择保持不变。我的建议是您使用每个树节点的非交互式表示形式(例如TextBlock)。然后,当调用EditLeafCommand时,将TextBox放在顶部,允许用户编辑节点。

关于c# - TreeView的HierarchicalDataTemplate中的键绑定(bind),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36865204/

10-13 06:26