9

コンテキスト メニューを含めるように ItemContainer をスタイリングしているリスト ボックスがあります。ここに同じのxamlがあります。

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
    ...
        <Setter Property="ContextMenu">
            <Setter.Value>
                <ContextMenu>
                    <MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup"/>
                </ContextMenu>
            </Setter.Value>
        </Setter>
    </Style>

以下に示すように、ViewModel でターゲット メソッドをコーディングしました。

public void DeleteGroup() { //ToDo
    ...
}

ViewModel は、ListBox がある UserControl の DataContext として設定されます。

上記のコードは、「メソッドのターゲットが見つかりません」という結果になります。なぜこれが機能しないのかわかりません。次のバリエーションも試しました

<MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup"
          cal:Action.Target="{Binding ElementName=UCRelayDispositionView, Path=DataContext}">

ここで、UCRelayDispositionView は UserControl の名前です。

上記のコードが機能しないのはなぜですか?

編集:1 次も試しました

<MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup"
          cal:Action.TargetWithoutContext="{Binding ElementName=UCRelayDispositionView, Path=DataContext}">

この

<MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup"
          cal:Action.TargetWithoutContext="{Binding ElementName=UCRelayDispositionView}">

編集: 2 ItemContainer で次の方法でタグを使用しようとしましたが、どちらも機能しません。

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="Tag" Value="{Binding Path=DataContext, ElementName=UCRelayDispositionView}"/>
        <Setter Property="ContextMenu">
            <Setter.Value>
                <ContextMenu>
                    <MenuItem Header="Remove Group" 
                              cal:Message.Attach="DeleteGroup()" 
                              cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"/>                                    
                    </ContextMenu>
            </Setter.Value>
    </Style>
</ListBox.ItemContainerStyle>

編集 3: バインディング エラー

System.Windows.Data Error: 40 : BindingExpression path error: 'PlacementTarget' property not found on 'object' ''MenuItem' (Name='')'. BindingExpression:Path=PlacementTarget.Tag; DataItem='MenuItem' (Name=''); target element is 'MenuItem' (Name=''); target property is 'TargetWithoutContext' (type 'Object')
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=UCRelayDispositionView'. BindingExpression:Path=DataContext; DataItem=null; target element is 'ContextMenu' (Name=''); target property is 'Tag' (type 'Object')
4

2 に答える 2

13

問題は、同じビジュアル ツリーに存在しない要素にターゲットをバインドしようとしていることにあります。たとえばContextMenu、アイテムが存在する があります。

ContextMenuアクション ターゲットを正しく取得するには、 sPlacementTargetプロパティを使用する必要があります。

XAML の SO に関する次の回答を確認してください。

Caliburn Micro の WPF コンテキスト メニュー

したがって、次の XAML が機能するはずです。

<MenuItem Header="Blah" cal:Message.Attach="SomeMethod()" cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}">

これは で を探し、アクションのターゲットをPlacementTargetContextMenuPlacementTarget.Tag( である必要がありますListBoxItem) に設定する必要があります。

ListBoxItem.Tag(すでに行ったように)DataContext親コンテナの に設定した場合( ListBox)、問題ありません

したがって、タグバインディングは次のようになります。

<Setter Property="Tag" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBox}}"/>

たとえば、全体は次のようになります。

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="Tag" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBox}}"/>
        <Setter Property="ContextMenu">
            <Setter.Value>
                <ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}">
                    <MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup()" />
                </ContextMenu>
            </Setter.Value>
        </Setter>
    </Style>
</ListBox.ItemContainerStyle>
于 2012-11-28T08:58:54.923 に答える