簡體   English   中英

TreeView 的 HierarchicalDataTemplate 中的 KeyBinding

[英]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

我怎么能叫EditLeafCommandLeafViewModel和發送參數?

您的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM