2016-04-26 145 views
1

我有一个TreeView。我想通过点击F2启用EditLeafCommandTreeView的HierarchicalDataTemplate中的KeyBinding

型号:

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

视图模型窗口:

public MainWindowViewModel{ 

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

视图模型的TreeView的:

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并发送参数?

+1

我不知道你在哪里结合SetSelectedItemCommand任何XAML,这似乎是问题的XAML,其中是吗? –

+1

是的,我可以看到没有一个名为SetSelectedItemCommand的属性,但是在XAML中必须有一个正在执行'{Binding SetSelectedItemCommand}' –

+0

@GlenThomas的地方,请参阅我的更新回答。我更新了信息,我想绑定到'LeafViewModel',而不是'MainViewModel'。他们真的很愚蠢的错误。抱歉。 – StepUp

回答

0

Andy ONeill has solved this problem.我真的很兴奋,他的解决方案:)。我赶紧分享这个解决方案与您:

绑定到一个命令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> 
1

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

只要树视图的选定项目更改,您也需要更新此属性。有很多种方法可以做到这一点。一种方法是使用Nuget包System.Windows.Interactivity.WPF。你将不得不增加一个命名空间声明:

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

然后,你的树视图的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),其在CommandParameterInvokeCommandAction元件结合使用。

此外,请注意,您必须在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放置在允许用户编辑节点的位置。

相关问题