[英]KeyBinding in HierarchicalDataTemplate of TreeView
我有一個TreeView
。 我想通過單擊F2來啟用EditLeafCommand
。
模型:
public class Leaf
{
public string LeafName { get; set; }
public bool HasChildren { get; set; }
}
窗口的視圖模型:
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 警告:56:為綁定 (hash=47044325) 創建了 BindingExpression (hash=2683661)
System.Windows.Data 警告:58:路徑:'EditLeafCommand'
System.Windows.Data 警告:60:BindingExpression (hash=2683661):默認模式解析為 OneWay
System.Windows.Data 警告:61:BindingExpression (hash=2683661):默認更新觸發器解析為 PropertyChanged
System.Windows.Data 警告:62:BindingExpression (hash=2683661):附加到 System.Windows.Input.KeyBinding.Command (hash=29578451)
System.Windows.Data 警告:64:BindingExpression (hash=2683661):使用框架導師
System.Windows.Data 警告:67:BindingExpression (hash=2683661):解析源
System.Windows.Data 警告:69:BindingExpression (hash=2683661):未找到框架導師
System.Windows.Data 警告:65:BindingExpression (hash=2683661):解析源延遲
System.Windows.Data 警告:95:BindingExpression(哈希=2683661):從 KeyBinding 獲得 InheritanceContextChanged 事件(哈希=29578451)
System.Windows.Data 警告:67:BindingExpression (hash=2683661):解析源
System.Windows.Data 警告: 70 : BindingExpression (hash=2683661): Found data context element: TreeView (hash=11903911) (OK)
System.Windows.Data 警告:78:BindingExpression(哈希=2683661):使用根項目 MainWindowViewModel 激活(哈希=44115416)
System.Windows.Data 警告:108:BindingExpression (hash=2683661):在級別 0 - 對於 MainWindowViewModel.EditLeafCommand 找到訪問器
System.Windows.Data 錯誤:40:BindingExpression 路徑錯誤:在“對象”“MainWindowViewModel”(HashCode=44115416)上找不到“EditLeafCommand”屬性。 BindingExpression:Path=EditLeafCommand; DataItem='MainWindowViewModel' (HashCode=44115416); 目標元素是“KeyBinding”(HashCode=29578451); 目標屬性是“命令”(類型“ICommand”)
System.Windows.Data 警告:80:BindingExpression (hash=2683661):TransferValue - 得到原始值 {DependencyProperty.UnsetValue}
System.Windows.Data 警告:88:BindingExpression (hash=2683661):TransferValue - 使用回退/默認值
System.Windows.Data 警告:89:BindingExpression(哈希=2683661):TransferValue - 使用最終值
我看到這篇文章, 這是同一個問題,但是,接受的答案沒有任何代碼(我試圖通過鏈接,但是,提供的方法對我沒有幫助)
錯誤說:
System.Windows.Data 錯誤:40:BindingExpression 路徑錯誤:在“對象”“MainWindowViewModel”上找不到“EditLeafCommand”屬性
但是我怎樣才能直接到EditLeadViewModel
?
我怎么能叫EditLeafCommand
從LeafViewModel
和發送參數?
您的MainViewModel
沒有SelectedItem
屬性。 您需要將此屬性添加到您的視圖模型,並確保在該屬性更改時觸發INotifyPropertyChanged.PropertyChanged
事件。
每當樹視圖的選定項更改時,您還需要更新此屬性。 有多種方法可以做到這一點。 一種方法是使用 Nuget 包System.Windows.Interactivity.WPF 。 您必須添加命名空間聲明:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
然后,在您的樹視圖 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
),該名稱在InvokeCommandAction
元素的CommandParameter
綁定中使用。
另請注意,您必須在MainViewModel
上添加SetSelectedItemCommand
。 此命令應設置我在開頭段落中描述的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
工作所需的基本內容。 但是,您還有另一個問題。 您的HierarchicalDataTemplate
將樹節點定義為TextBox
。 當您單擊TextBox
沒有單擊冒泡到TreeView
並且選擇不會更改。 我的建議是您使用每個樹節點的非交互式表示(例如TextBlock
)。 然后,當EditLeafCommand
被調用時,您將一個TextBox
放在頂部,允許用戶編輯節點。
Andy ONeill 已經解決了這個問題。 我對他的解決方案感到非常興奮:)。 趕緊把這個解決方案分享給大家:
要綁定到LeafViewModel
的命令:
<TreeView ItemsSource="{Binding Leafs}" Name="tv">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:LeafViewModel}"
ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<Label VerticalAlignment="Center" FontFamily="WingDings" Content="1"/>
<TextBox Text="{Binding LeafName}" Tag="{Binding DataContext,
RelativeSource={RelativeSource Self}}" Background="Transparent">
<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.InputBindings>
<KeyBinding Key="F2" Command="{Binding SelectedItem.EditLeafCommand, ElementName=tv}"/>
</TreeView.InputBindings>
</TreeView>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.