Caliburn Message.Attach()抛出"找不到方法的目标"

Jat*_*tin 7 c# wpf caliburn.micro wpf-4.0

我有一个列表框,我正在为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>
Run Code Online (Sandbox Code Playgroud)

我在ViewModel中编写了目标方法,如下所示.

public void DeleteGroup() { //ToDo
    ...
}
Run Code Online (Sandbox Code Playgroud)

ViewModel被设置为UserControl的DataContext,其中有ListBox.

上面的代码导致"找不到方法的目标".我不知道为什么这不起作用.我也试过以下变化

<MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup"
          cal:Action.Target="{Binding ElementName=UCRelayDispositionView, Path=DataContext}">
Run Code Online (Sandbox Code Playgroud)

其中UCRelayDispositionView是UserControl的名称.

为什么上面的代码不起作用?

编辑:1 还尝试了以下内容

<MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup"
          cal:Action.TargetWithoutContext="{Binding ElementName=UCRelayDispositionView, Path=DataContext}">
Run Code Online (Sandbox Code Playgroud)

还有这个

<MenuItem Header="Remove Group" cal:Message.Attach="DeleteGroup"
          cal:Action.TargetWithoutContext="{Binding ElementName=UCRelayDispositionView}">
Run Code Online (Sandbox Code Playgroud)

编辑:2 我试图在ItemContainer上以下列方式使用Tag,但它也不起作用.

<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>
Run Code Online (Sandbox Code Playgroud)

编辑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')
Run Code Online (Sandbox Code Playgroud)

Cha*_*leh 11

您的问题在于您尝试将目标绑定到同一视觉树中不存在的元素,例如,您有一个ContextMenu项目所在的元素.

要正确获取操作目标,您需要使用ContextMenus PlacementTarget属性.

有关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}}">
Run Code Online (Sandbox Code Playgroud)

这应该查找PlacementTargeton ContextMenu并将action的目标设置为值PlacementTarget.Tag(应该是ListBoxItem).

如果你设置ListBoxItem.Tag(就像你已经完成的那样)是DataContext父容器(ListBox你),你应该没问题

所以标签绑定应该是:

<Setter Property="Tag" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBox}}"/>
Run Code Online (Sandbox Code Playgroud)

例如,整个事情应该是:

<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>
Run Code Online (Sandbox Code Playgroud)

  • 这个答案令人困惑.如果代码不正确,请删除它并在答案中只有正确的代码.如果他们想要查看您所做的编辑,人们可以查看修订历史记录.使用下面的"编辑"部分保持不正确的代码对任何人都没有帮助. (3认同)