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