我试图在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无法可靠地解决方法。我确定这是一个常见的问题,我已经尝试了一些我在网上找到的东西,但似乎没有任何工作。
任何想法??
答案 0 :(得分:24)
使用我在Caliburn Micro site上找到的信息,我修改了您的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。
答案 1 :(得分:0)
添加到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