Caliburn Micro 中的 WPF 上下文菜单

14

我正在尝试在一个ListBox ItemTemplate中获取上下文菜单,以调用父视图模型中的方法,并将所点击的项作为参数传递。我已经在该项模板中为其他按钮实现了此功能,但对于上下文菜单似乎无法正常工作。

我有以下XAML代码(为了清晰起见进行了缩写):

<ListBox>
    <ListBox.GroupStyle>
        <GroupStyle>
            ...
        </GroupStyle>
    </ListBox.GroupStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ContextMenu>
                    <ContextMenu Name="cm">
                        <MenuItem Header="Open" 
                                  cal:Message.Attach="Open($dataContext)">

                        </MenuItem>
                </Grid.ContextMenu>

                <TextBlock VerticalAlignment="Center" >
                    .. text..
                </TextBlock>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

我有一种感觉,这可能与可视化树的不同有关,因此Caliburn无法可靠地解析该方法。我相信这是一个常见的问题,我已经尝试了网上找到的一些方法,但似乎没有任何作用。

有什么想法吗?

2个回答

29

根据我在Caliburn Micro网站找到的信息,我修改了你的XAML,使它看起来像这样:

  <Grid Background="White" HorizontalAlignment="Stretch" Height="200" Name="GridLayout">       
    <ListBox x:Name="ListBoxItems">            
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid Tag="{Binding DataContext, ElementName=GridLayout}">
                    <Grid.ContextMenu>
                        <ContextMenu Name="cm" cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
                            <MenuItem Header="Open" 
                              cal:Message.Attach="Open($dataContext)">
                            </MenuItem>
                        </ContextMenu>
                    </Grid.ContextMenu>

                    <TextBlock VerticalAlignment="Center" >
                .. text..
                    </TextBlock>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

我的视图模型:

    public List<string> ListBoxItems { get; set; }
    public ShellViewModel()
    {
        ListBoxItems = new List<string> {"One", "Two", "Three"};          
    }

    public void Open(object source)
    {
        MessageBox.Show((string) source);
    }

已成功使用来自列表框的适当字符串调用了Open函数。


2
我不知道为什么这个没有被接受。它对我帮助很大,谢谢你。 - Jony Adamit

1

在Jason的答案基础上,如果您将使用与控件相同的数据上下文,则可以绑定DataContext而不是Tag

<Grid>
    <Grid.ContextMenu>
        <ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
            <MenuItem Header="Open" 
                      cal:Message.Attach="Open($source)">
            </MenuItem>
        </ContextMenu>
    </Grid.ContextMenu>
</Grid>

$source 触发 ActionMessage 的实际 FrameworkElement

您可以在此处查看有关 $source 约定的更多信息:https://caliburnmicro.com/documentation/cheat-sheet


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接