3

私は持っTreeViewていHierarchicalDataTemplateます。私TreeViewが持っているContextMenu

<TreeView Name="_packageTreeView" ItemsSource="{Binding PackageExtendedList}" Behaviors:TreeViewInPlaceEditBehavior.IsEditable="True">
    <TreeView.ContextMenu>
        <ContextMenu StaysOpen="true">
            <MenuItem Header="Добавить пакет" Height="20" Command="{Binding AddPackageCommand}" 
                CommandParameter="{Binding ElementName=_packageTreeView, Path=SelectedItem}">
                    <MenuItem.Icon>
                        <Image Source="/Resources/ManualAdd.png" Width="15" Height="15"></Image>
                    </MenuItem.Icon>
            </MenuItem>
        </ContextMenu>
   </TreeView.ContextMenu>
   <TreeView.ItemTemplate>
       <HierarchicalDataTemplate ItemsSource="{Binding Childs}">bla bla bla</HierarchicalDataTemplate>
   </TreeView.ItemTemplate>
</TreeView>

ご覧のとおり、Commandメニュー項目にバインドします。AddPackageCommand は通常どおり ViewModel クラスで定義されます。Invoke コマンドは正常に動作しますが、null常にCommandParameter. 似たような質問をいくつか見つけましたが、解決策がわかりません。例えば:

WPF の ContextMenu の CommandParameters

とにかく、私にはうまくいきません:(何が間違っているのですか?

更新しました

それは機能しているようですが、それはすべて同じです。なぜ が機能しないのかわかりCommandParameterませんTreeView.Name

CommandParameter="{Binding PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"

たとえば、そのようなサンプルは正常に動作します

<i:EventTrigger EventName="SelectedItemChanged">
    <i:InvokeCommandAction Command="{Binding PackageTreeItemChangeCommand}" CommandParameter="{Binding ElementName=_packageTreeView, Path=SelectedItem}"/>
</i:EventTrigger>

ちくしょうマジかよ...

とにかく、私はではなくにTreeViewオブジェクトを持っています。から取得できますが、正確に を送信するにはどうすればよいですか?CommandParameterTreeViewItemSelectedItemTreeViewTreeViewItemCommandParameter

シェリダンへ

質問は、なぜこれが機能しないのかということでした。

CommandParameter="{Binding ElementName=_packageTreeView, Path=SelectedItem}"

そして、これは機能します

CommandParameter="{Binding PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"

TreeView コントロール名を直接使用できる場合と使用できない場合があるのはなぜですか。TreeView私が理解しているように、問題はコントロールの DataContext とは異なり、独自の VisualTree があり、の一部ではないためContextMenuです。ContextMenuTreeView ViaualTree

残念ながら、そのアプローチもうまくいきませnull。確かに TreeView.Tag を設定しました。

<ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={
            RelativeSource Self}}" StaysOpen="true">
    <MenuItem Header="Добавить пакет" Height="20" Command="{Binding AddPackageCommand}" 
                CommandParameter="{Binding ElementName=_packageTreeView, Path=SelectedItem}">
        <MenuItem.Icon>
             <Image Source="/Resources/ManualAdd.png" Width="15" Height="15"></Image>
        </MenuItem.Icon>
    </MenuItem>
</ContextMenu>

これが最も簡単な方法ですが、ViewModel に SelectedItem プロパティがある場合、CommandParameter既に ViewModel にあるため、それを にバインドしても意味がありません。

 <MenuItem Header="Добавить пакет" Height="20" Command="{Binding AddPackageCommand}" 
    CommandParameter="{Binding SelectedItem}">
    <MenuItem.Icon>
        <Image Source="/Resources/ManualAdd.png" Width="15" Height="15"></Image>
    </MenuItem.Icon>
</MenuItem>
4

1 に答える 1

2

あなたはすでに答えを持っていることを私たちに示しました...一体なぜ、単に答えの例に従うのではなく、この同じ主題についてさらに別の質問を投稿したのですか? 答えを適切にコピーしなかったため、うまくいきません。

投稿の回答の例では、TagプロパティはTreeViewメニューが適用されるコントロールに設定されていますが、これを行っていません。

次の問題は、このTagプロパティを再び無視したことCommandParameterです...どういうわけか、これを正しい答えから変更しました:

CommandParameter="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource 
    FindAncestor, AncestorType={x:Type ContextMenu}}}

あなたの質問でこれに:

CommandParameter="{Binding PlacementTarget, RelativeSource={RelativeSource 
    FindAncestor, AncestorType={x:Type ContextMenu}}}"

コピーして貼り付けるだけでした。それでも、これを行うとさらに運が良くなる可能性があります。

<TreeView Tag="{Binding DataContext, RelativeSource={RelativeSource Self}}" 
    Name="_packageTreeView" ItemsSource="{Binding PackageExtendedList}" 
    Behaviors:TreeViewInPlaceEditBehavior.IsEditable="True">
    <TreeView.ContextMenu>
        <ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={
            RelativeSource Self}}" StaysOpen="true">
            <MenuItem Header="Добавить пакет" Height="20" Command="{Binding AddPackageCommand}" 
                CommandParameter="{Binding ElementName=_packageTreeView, Path=SelectedItem}">
                    <MenuItem.Icon>
                        <Image Source="/Resources/ManualAdd.png" Width="15" Height="15"></Image>
                    </MenuItem.Icon>
            </MenuItem>
        </ContextMenu>
   </TreeView.ContextMenu>
   <TreeView.ItemTemplate>
       <HierarchicalDataTemplate ItemsSource="{Binding Childs}">bla bla bla</HierarchicalDataTemplate>
   </TreeView.ItemTemplate>
</TreeView>

プロパティを見てくださいTreeView.Tag...これは独自のに設定されています。つまり、 のDataContextとして設定されているものはすべて、プロパティ オブジェクトで使用できるようになりました。DataContextTreeViewTag

次に、ContextMenu.DataContextプロパティを見てください...これは、 が適用されるコントロールであるのTagプロパティに設定されています。この場合は、.PlacementTargetContextMenuTreeview

まだ解決していない場合は、DataContextContextMenuが の と同じオブジェクトに設定されていることを意味DataContextしますTreeViewCommand別のオブジェクト上にあるためにこれが必要でない場合はBinding、プロパティ内のパスを変更Tagして、オブジェクトが存在する場所を指すようにしますCommand

これを簡単にするためにできる最後のことは、プロパティにバインドするビュー モデル/コード ビハインドにプロパティを追加することですTreeView.SelectedItem

<TreeView SelectedItem="{Binding SelectedItem}"... />

次に、このプロパティを単純に参照できますCommandParameter

<MenuItem Header="Добавить пакет" Height="20" Command="{Binding AddPackageCommand}" 
    CommandParameter="{Binding SelectedItem}">
    <MenuItem.Icon>
        <Image Source="/Resources/ManualAdd.png" Width="15" Height="15"></Image>
    </MenuItem.Icon>
</MenuItem>

Tagもちろん、この最後の部分では、ビュー モデル/コード ビハインドを のプロパティとして設定していることを前提としていますTreeView。それでも理解できない場合は、WPF Tutorial.NETの WPF のコンテキスト メニューのページを参照してください。

更新 >>>

なぜこの質問を投稿したのか理解できません。最初にあなたは何かできないと言いましたが、別の投稿で有効な解決策へのリンクを提供してくれました。あなたを助けようとした後、あなたはそれがうまくいったと言いましたが、その理由はわかりません...しかし、あなたは自分の質問に再び正しく答えました:

私が理解しているように、ContextMenuには独自のVisualTreeがあり、TreeView ViaualTreeの一部ではないため、TreeViewコントロールとContextMenuのDataContextは異なります。

あなたが言ったように、にContextMenuは独自のビジュアルツリーがあります。これは、別のビジュアル ツリーにある、名前が付けられているかどうかにかかわらず、コントロールを認識しないことを意味します。ただし、ContextMenu.DataContext含まれているビューなどのオブジェクトが に提供されている場合は、別のビジュアル ツリー (より具体的には、ビュー内のコントロールのビジュアル ツリー) 内のコントロールを認識することができます。

Bindingこの問題全体は、一般的なBinding.Path構文とより具体的な構文に関する知識の欠如に起因しているようです。このトピックの詳細については、MSDN の次の記事を参照してください。

Binding.Path プロパティ

プロパティ パスの構文

RelativeSource MarkupExtension

非常に多くの人が、歩けるようになる前に WPF で走ろうとします。

于 2013-10-02T09:59:38.523 に答える