我有一个应用程序,它将ViewModel列表显示为选项卡控件。项目列表数据绑定到父ViewModel上的属性。 现在我想添加一个上下文菜单来支持每个 TabItems(而不是整个TabControl本身)的操作。
这是有问题的控件:
<TabControl x:Name="Items"
Grid.Column="2"
Grid.Row="0"
Margin="3,5,5,3"
Visibility="{Binding Path=TabControlVisible, Converter={StaticResource BooleanToVisibilityConverter}}">
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding DisplayName}" />
<Button Padding="10,0,0,0"
Content="X"
Style="{DynamicResource NoChromeButton}"
cal:Message.Attach="CloseTab($dataContext)" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
当我将上下文菜单代码放在TabControl标记内时,上下文菜单iis作为整体注册了TabControl。这不是我想要的行为。
如果我将它添加到DataTemplate标签内的StackPanel标签,则为每个Item注册的DataTriggers将在子ViewModel上执行,但视图模型没有执行该事件的方法和属性。
有可能解决这个问题吗?如何为每个项目添加上下文菜单以支持以下操作:“关闭此”,“保存此项”,“关闭除此之外的所有内容”
更多信息:
我使用Caliburn.Micro作为框架并使用它的约定将TabControl
绑定到ViewModel上的Items
属性,这是通过从IObservableCollection<LocationDetailsViewModel>
继承我的ViewModel而创建的Conductor<LocationDetailsViewModel>.Collection.OneActive
。 LocationsDetailsViewModel
也继承自Screen
一切都按预期运作。如果我向Items
属性添加项目,则TabControl
会正确更新。
我想在每个 ContextMenu
项目中添加TabControl
,可以通过右键单击标题来访问该项目。然后上下文菜单应包含操作,如“关闭此”,“保存此”,“关闭除此之外的所有内容”
为此,我向StackPanel
添加了一个上下文菜单,它控制了标题的设计,并使用CM在视图模型上调用适当的方法。但是当我调用它时,我得到一个例外,告诉我没有找到合适的方法。
我仔细检查过,似乎CM想要在LocationDetailsViewModel
而不是LocationViewModel
上调用方法,即使每个标签项的关闭按钮中存在类似的方法调用。
以下是具有上下文菜单的代码:
<UserControl x:Class="RpgTools.LocationPresenter.Views.LocationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cal="http://www.caliburnproject.org"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:vm="clr-namespace:RpgTools.LocationPresenter.ViewModels"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=vm:LocationViewModel, IsDesignTimeCreatable=True}"
cal:Bind.AtDesignTime="True"
Padding="5">
<!-- Code left out for brevity -->
<TabControl x:Name="Items"
Grid.Column="2"
Grid.Row="0"
Margin="3,5,5,3"
Visibility="{Binding Path=TabControlVisible, Converter={StaticResource BooleanToVisibilityConverter}}">
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="Close This"
cal:Message.Attach="CloseTab($dataContext)">
</MenuItem>
</ContextMenu>
</StackPanel.ContextMenu>
<TextBlock Text="{Binding DisplayName}" />
<Button Padding="10,0,0,0"
Content="X"
Style="{DynamicResource NoChromeButton}"
cal:Message.Attach="CloseTab($dataContext)" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
答案 0 :(得分:0)
ContextMenus不像其他控件那样是正常的VisualTree的一部分,因此.DataContext
不会像预期的那样继承用于绑定目的。
您需要将ContextMenu.DataContext
绑定到ContextMenu.PlacementTarget.DataContext
,在这种情况下为StackPanel.DataContext
。
<ContextMenu DataContext="{Binding
RelativeSource={RelativeSource Self},
Path=PlacementTarget.DataContext}">