c# - TreeView 的 HierarchicalDataTemplate 中的键绑定(bind)

标签 c# wpf xaml mvvm treeview

我有一个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>

输出窗口:

System.Windows.Data Warning: 56 : Created BindingExpression (hash=2683661) for Binding (hash=47044325)

System.Windows.Data Warning: 58 : Path: 'EditLeafCommand'

System.Windows.Data Warning: 60 : BindingExpression (hash=2683661): Default mode resolved to OneWay

System.Windows.Data Warning: 61 : BindingExpression (hash=2683661): Default update trigger resolved to PropertyChanged

System.Windows.Data Warning: 62 : BindingExpression (hash=2683661): Attach to System.Windows.Input.KeyBinding.Command (hash=29578451)

System.Windows.Data Warning: 64 : BindingExpression (hash=2683661): Use Framework mentor

System.Windows.Data Warning: 67 : BindingExpression (hash=2683661): Resolving source

System.Windows.Data Warning: 69 : BindingExpression (hash=2683661): Framework mentor not found

System.Windows.Data Warning: 65 : BindingExpression (hash=2683661): Resolve source deferred

System.Windows.Data Warning: 95 : BindingExpression (hash=2683661): Got InheritanceContextChanged event from KeyBinding (hash=29578451)

System.Windows.Data Warning: 67 : BindingExpression (hash=2683661): Resolving source

System.Windows.Data Warning: 70 : BindingExpression (hash=2683661): Found data context element: TreeView (hash=11903911) (OK)

System.Windows.Data Warning: 78 : BindingExpression (hash=2683661): Activate with root item MainWindowViewModel (hash=44115416)

System.Windows.Data Warning: 108 : BindingExpression (hash=2683661): At level 0 - for MainWindowViewModel.EditLeafCommand found accessor

System.Windows.Data Error: 40 : BindingExpression path error: 'EditLeafCommand' property not found on 'object' ''MainWindowViewModel' (HashCode=44115416)'. BindingExpression:Path=EditLeafCommand; DataItem='MainWindowViewModel' (HashCode=44115416); target element is 'KeyBinding' (HashCode=29578451); target property is 'Command' (type 'ICommand')

System.Windows.Data Warning: 80 : BindingExpression (hash=2683661): TransferValue - got raw value {DependencyProperty.UnsetValue}

System.Windows.Data Warning: 88 : BindingExpression (hash=2683661): TransferValue - using fallback/default value

System.Windows.Data Warning: 89 : BindingExpression (hash=2683661): TransferValue - using final value

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

错误提示:

System.Windows.Data Error: 40 :BindingExpression path error: 'EditLeafCommand' property not found on 'object' ''MainWindowViewModel'

但是我如何定向到 EditLeadViewModel

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

最佳答案

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

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

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

然后,在 TreeView XAML 元素内添加以下内容(我仅显示要添加的内容 - 保持 TreeView 元素内 XAML 的其余部分完好无损):

<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 中使用绑定(bind)在 InvokeCommandAction元素。

另外,请注意,您必须添加 SetSelectedItemCommandMainViewModel 。此命令应设置 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;
  }

}

这是启用键绑定(bind)到 SelectedItem.EditLeafCommand 所需的基本内容上类。但是,您还有另一个问题。您的HierarchicalDataTemplate将树节点定义为 TextBox 。当您点击 TextBox没有点击冒泡到 TreeView并且选择没有改变。我的建议是您使用每个树节点的非交互式表示(例如 TextBlock )。然后,当 EditLeafCommand被调用时您输入 TextBox顶部允许用户编辑节点。

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

相关文章:

c# - 如何更改 WPF 中的按钮样式,由 bool 值触发?

c# - 从另一个 WPF 应用程序加载 WPF 应用程序程序集,在同一 AppDomain 中获取错误 : Cannot create more than one System. Windows.Application 实例

xaml - 如何将 xamarin 表单中的选项卡 2 设置为启动时的默认选项卡

c# - 列表框不显示特定对象的值(数据绑定(bind))

c# - 求一个C#或者VB.net的爬虫

c# - 如何在使用 FileSystemWatcher 监视多个文件夹的应用程序中监视多个共享文件

c# - 有没有更好的方法来订购 IEnumerable 以匹配任意顺序?

c# - 静态字符串的链式插值无法按预期工作

wpf - 绑定(bind)图像源属性

WPF : Custom Button