【发布时间】:2020-01-07 03:30:01
【问题描述】:
我有一个按钮,当用户左键单击它时,我想显示一个弹出菜单。我已将弹出窗口实现为按钮的ContextMenu。需要通过绑定到各种ViewModel 属性来控制上下文菜单中菜单项的可用性。如您所知,ContextMenus 存在于与父窗口不同的可视树上,因此我不得不做一些研究以弄清楚如何将ContextMenu 的DataContext 设置为与父控件(即按钮)。我是这样做的:
<Button Name="AddRangeBtn" Height="50" Width="50" Margin="5"
**Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}}">**
<Button.Content>
<Image Source="{StaticResource DmxPlusIconImage}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
MaxHeight="50" MaxWidth="50" Margin="-10" />
</Button.Content>
<Button.ToolTip>
<ToolTip Style="{DynamicResource DMXToolTipStyle}"
Content="{x:Static Localization:StringResources.AddFrequencyRangeTooltip}"/>
</Button.ToolTip>
<Button.ContextMenu>
**<ContextMenu Name="AddRngContextMenu"
DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">**
<MenuItem Style="{StaticResource localMenuItem}"
IsEnabled="{Binding CanAddLinearRange}">
<MenuItem.ToolTip>
<ToolTip Style="{DynamicResource DMXToolTipStyle}"
Content="{x:Static Localization:StringResources.ToolTip_AddLinearFrequencyRange}"/>
设置 datacontext 的技巧是将 contextmenu 的 datacontext 绑定到 contextmenu 中的 PlacementTarget.Tag 并在按钮中添加相应的 Tag 属性。有了这些,我就可以直接将MenuItems 中的属性(如IsEnabled="{Binding CanAddLinearRange}")绑定到ViewModel 的依赖属性。当我通过右键单击按钮访问上下文菜单时,这一切都很好,但我希望菜单通过正常的左键单击显示。所以,我在按钮上添加了以下EventTrigger:
<Button.Triggers>
<EventTrigger SourceName="AddRangeBtn" RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="AddRngContextMenu" Storyboard.TargetProperty="(ContextMenu.IsOpen)">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<system:Boolean>True</system:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
这样,右键单击按钮会显示上下文菜单,但是该上下文菜单的实例似乎没有获得与右键单击显示的实例相同的数据上下文!!!在左键版本中,菜单中的所有项目都已启用,因此很明显,上下文菜单没有从视图模型中看到依赖项属性。我什至不知道这怎么可能有两种不同版本的上下文菜单,一种具有正确的数据上下文,另一种具有默认行为。
右键单击启动时的上下文菜单:
右键单击启动时的上下文菜单:
我正在使用 XAML 来创建左键单击行为,并且在一些示例中,我看到人们使用代码隐藏来实现左键单击上下文菜单,他们将上下文菜单的数据上下文设置为button.click 事件处理程序中的 button.datacontext。我猜这也是我需要做的,但我不知道如何在 xaml 中做到这一点。
任何想法都将受到高度赞赏。
【问题讨论】:
-
@vatbub - 我喜欢你对问题的编辑,但我认为你为第二张图片选择了错误的链接,直到我接受你的更改才意识到这一点。我不被允许嵌入图片,所以它们被添加为链接,但第二张图片应该显示所有项目都已启用。
-
对不起,我现在修好了。不幸的是,我还必须在答案末尾添加一些 .... 以使 StackOverflow 接受编辑。不过,您应该能够将这些点编辑掉。再次抱歉????