5

かなり話題になっているようですが…

次の XAML があります。

<internal:MyCommandObject x:Name="CommandModel"/>

<Button DockPanel.Dock="Bottom" Command="{Binding DoAction, ElementName=CommandModel}">
    <Button.ContextMenu>
        <ContextMenu DataContext="{Binding PlacementTarget, RelativeSource={RelativeSource Self}}">
            <MenuItem Command="{Binding DoAction, ElementName=CommandModel}"/>
        </ContextMenu>
    </Button.ContextMenu>
    Click Me
</Button>

は、MyCommandObjectその から動的コマンドを公開するコントロールDataContextです。あなたは次に何が来るか知っています。:)

基本的に、ボタン コマンドは完全に機能します。クリックすると、DoActionコマンドMyCommandObjectが完全に実行されます。ただし、メニュー項目のコマンドは実行されません。コントロールのビジュアル ツリーをトラバースできるようにコンテキスト メニューdatacontextを設定するなど、さまざまなトリックを試しましたが、何もしていません。placementTarget

RelativeSourceこれを機能させるには、とルーンの特定の調整がCommandTarget必要ですか?

4

1 に答える 1

3

これは、DataContext="{Binding PlacementTarget,...バインディングがボタンを MenuItems として設定するが、ウィンドウの VisualTree にDataContext追加されず、バインディングが機能しないために発生します。バインディングを使用する簡単な回避策は、これを Window/UserControl のコード ビハインドに追加することです。ContextMenuElementNameElementName

NameScope.SetNameScope(contextMenuName, NameScope.GetNameScope(this)); 

別の解決策はこれを行うことです -

<ContextMenu DataContext="{Binding PlacementTarget, RelativeSource={RelativeSource Self}}">   
    <MenuItem Command="{Binding DataContext.DoAction}"/>   
</ContextMenu>

DataContext="{Binding PlacementTarget,...Button(Placementtarget) を ContextMenu の DataContext として設定するため、Button の DataContext を使用してコマンドをバインドできます。

アップデート:

NameScope.NameScope添付プロパティを使用して XAML で NameScope を設定することはできますが、コードなしで親ウィンドウの NameScope を取得する方法がわかりません!

Josh Smith による次の記事と同様のことを行う必要があります。彼は XAML でこれを行う方法を提供しています。しかし、それにもコードが含まれます(コードの1行以上)-

ElementSpy で ElementName バインディングを有効にする

この 1 行のコードを使用しない特定の理由はありますか?

于 2012-07-05T06:45:00.800 に答える