gpt4 book ai didi

wpf - 按钮上的上下文菜单单击不触发命令

转载 作者:行者123 更新时间:2023-12-04 06:29:48 25 4
gpt4 key购买 nike

这里有个问题。

我在单击按钮时显示上下文菜单,菜单命令绑定(bind)到 View 模型中的 ICommand。单击按钮和右键单击时都会显示菜单。问题是当我单击按钮然后单击上下文菜单时菜单单击没有触发,但是当我右键单击按钮然后单击菜单时我可以确认菜单正在工作。

 <Button Grid.Row="3" Width="500" Height="30" Name="cmButton"  >
Button with Context Menu
<Button.ContextMenu>
<ContextMenu DataContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Mode=Self}}" >
<MenuItem DataContext="{Binding}" Header="New Layout Element..." Command="{Binding Path=SubmitBtn}" />
</ContextMenu>
</Button.ContextMenu>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<EventTrigger RoutedEvent="Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="ContextMenu.IsOpen">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>

我可以确认我的 View 模型没有任何问题,因为当我右键单击按钮然后单击上下文菜单时命令正在触发。

最佳答案

当您手动设置 ContextMenu.IsOpen 属性时,

PlacementTargetnull,因为它仅在通过右键单击打开后才设置为实际值目标控制。 (PopUpService 类负责将此值设置为实际目标)。

由于 PlacementTargetnull,以防您通过 Storyboard 打开它时,绑定(bind)无法解析它所绑定(bind)的实际命令到。

所以,问题是您需要将 ButtonDataContext 传递给 MenuItem 以便解决绑定(bind)问题。 (MenuItem 与按钮的可视化树不同)。这可以通过两种方式实现:


使用 x:Reference(在 WPF 4.0 及更高版本中可用)但您需要声明虚拟控件,以便可以引用它来获取 DataContextVisibility 设置为 Collapsed

<FrameworkElement x:Name="dummyControl" Visibility="Collapsed"/>
<Button Width="100" Height="30" Name="cmButton">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="New Layout Element..."
Command="{Binding Path=DataContext.SubmitBtn,
Source={x:Reference dummyControl}}" />
</ContextMenu>
</Button.ContextMenu>
</Button>

另一个有趣的事情是 Freezable 对象继承 DataContext 即使它们不在 VisualTree 中所以我们可以使用此功能来克服我们需要继承 DataContext 的情况。

首先我们需要创建继承自Freezable的类并公开可以绑定(bind)到的DP:

public class BindingProxy : Freezable
{
#region Overrides of Freezable

protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}

#endregion

public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}

public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy));
}

现在我们可以像这样在 XAML 中使用它:

<Button Width="100" Height="30" Name="cmButton">
<Button.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding}"/>
</Button.Resources>
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="New Layout Element..."
Command="{Binding Path=Data.SubmitBtn,
Source={StaticResource proxy}}" />
</ContextMenu>
</Button.ContextMenu>
</Button>

关于wpf - 按钮上的上下文菜单单击不触发命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21355670/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com