WPF ContextMenu
的默认行为是在用户右键单击时显示它。我希望当用户单击鼠标左键时显示 ContextMenu
。看起来这应该是 ContextMenu 上的一个简单属性,但事实并非如此。
我对其进行了操纵,以便在代码隐藏中处理 LeftMouseButtonDown
事件,然后显示上下文菜单。
我在项目中使用 MVVM,这意味着我对具有上下文菜单的项目使用 DataTemplate
。摆脱代码隐藏并找到一种使用 XAML 中的触发器或属性来显示上下文菜单的方法会更加优雅。
对于这个问题有什么想法或解决方案吗?
最佳答案
我刚刚根据 HK1 的答案编写并测试了这个(您还可以在 Attached Properties Overview) 中阅读有关附加属性的信息:
public static class ContextMenuLeftClickBehavior
{
public static bool GetIsLeftClickEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(IsLeftClickEnabledProperty);
}
public static void SetIsLeftClickEnabled(DependencyObject obj, bool value)
{
obj.SetValue(IsLeftClickEnabledProperty, value);
}
public static readonly DependencyProperty IsLeftClickEnabledProperty = DependencyProperty.RegisterAttached(
"IsLeftClickEnabled",
typeof(bool),
typeof(ContextMenuLeftClickBehavior),
new UIPropertyMetadata(false, OnIsLeftClickEnabledChanged));
private static void OnIsLeftClickEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var uiElement = sender as UIElement;
if(uiElement != null)
{
bool IsEnabled = e.NewValue is bool && (bool) e.NewValue;
if(IsEnabled)
{
if(uiElement is ButtonBase)
((ButtonBase)uiElement).Click += OnMouseLeftButtonUp;
else
uiElement.MouseLeftButtonUp += OnMouseLeftButtonUp;
}
else
{
if(uiElement is ButtonBase)
((ButtonBase)uiElement).Click -= OnMouseLeftButtonUp;
else
uiElement.MouseLeftButtonUp -= OnMouseLeftButtonUp;
}
}
}
private static void OnMouseLeftButtonUp(object sender, RoutedEventArgs e)
{
Debug.Print("OnMouseLeftButtonUp");
var fe = sender as FrameworkElement;
if(fe != null)
{
// if we use binding in our context menu, then it's DataContext won't be set when we show the menu on left click
// (it seems setting DataContext for ContextMenu is hardcoded in WPF when user right clicks on a control, although I'm not sure)
// so we have to set up ContextMenu.DataContext manually here
if (fe.ContextMenu.DataContext == null)
{
fe.ContextMenu.SetBinding(FrameworkElement.DataContextProperty, new Binding { Source = fe.DataContext });
}
fe.ContextMenu.IsOpen = true;
}
}
}
...
<Button Content="Do All" local:ContextMenuLeftClickBehavior.IsLeftClickEnabled="True" >
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="Make everything awesome" />
<MenuItem Header="Control the World" />
</ContextMenu>
</Button.ContextMenu>
</Button>
(请注意 OnMouseLeftButtonUp() 方法内的注释)
关于.net - 仅使用 XAML 在左键单击时显示上下文菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/555252/