2016-04-26 15 views
1

私はTreeViewを持っています。 F2をクリックしてEditLeafCommandを有効にします。TreeViewの階層型テンプレートのKeyBinding

モデル:ウィンドウの

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

ビューモデル:ツリービューの

public MainWindowViewModel{ 

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

ビューモデル:

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にどうすればいいですか?

EditLeafCommandLeafViewModelから呼び出してパラメータを送信するにはどうすればよいですか。

+1

私はどこ、問題のXAMLのようですあなたがSetSelectedItemCommandに結合されているすべてのXAMLを、表示されませんそれは...ですか? –

+1

はい、SetSelectedItemCommandというプロパティはありませんが、{バインディングSetSelectedItemCommand} ' –

+0

@GlenThomasを実行しているXAMLのどこかにある必要があります。最新の回答をご覧ください。私は情報を更新したので、 'MainViewModel'ではなく' LeafViewModel'にバインドしたいと思います。彼らは本当に愚かな間違いです。ごめんなさい。 – 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イベントが発生することを確認する必要があります。

ツリービューの選択項目が変更されたときにも、このプロパティを更新する必要があります。それを行うにはさまざまな方法があります。 1つの方法はNugetパッケージSystem.Windows.Interactivity.WPFを使用することです。 (私は追加するには何を示しています - TreeView要素そのまま内部であなたのXAMLの残りの部分を保つ)以下を追加するには、ツリービューのXAML要素の内部、そして、

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

:あなたは、名前空間宣言を追加する必要があります。 InvokeCommandAction要素に結合CommandParameterで使用さTreeView要素名(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> 

注意。

さらに、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; 
    } 

} 

これは仕事にSelectedItem.EditLeafCommandに結合し、あなたのキーを有効にするために必要な基本的なものです。しかし、別の問題があります。HierarchicalDataTemplateは、ツリーノードをTextBoxと定義しています。 TextBoxをクリックすると、クリックはTreeViewにバブリングされず、選択は変更されません。私は、各ツリーノードの非インタラクティブ表現(例:TextBlock)を使用することをお勧めします。次に、EditLeafCommandが呼び出されると、ユーザはノードを編集できるように、TextBoxを上に置きます。