tim*_*ath 7 .net wpf xaml contextmenu mvvm
WPF的默认行为ContextMenu是在用户右键单击时显示它.我希望在ContextMenu用户左键单击时显示.看起来这应该是一个简单的属性ContextMenu,但事实并非如此.
我操纵它,以便我LeftMouseButtonDown在代码隐藏中处理事件,然后显示上下文菜单.
我在我的项目中使用MVVM,这意味着我将DataTemplates用于具有上下文菜单的项目.摆脱代码隐藏并找到一种使用XAML中的触发器或属性显示上下文菜单的方法会更加优雅.
这个问题的任何想法或解决方案?
我建议做的是创建一个带有DependencyProperty的新静态类.调用类LeftClickContextMenu和属性Enabled(只是想法).注册DependencyProperty时添加一个更改后的回调.然后在属性更改回调中,如果Enabled设置为true,则向LeftMouseButtonDown事件添加处理程序并在那里执行您的操作.如果Enabled设置为false,则删除处理程序.这可以让你只需在你的xaml中使用以下内容就可以将它设置为任何属性.
<Border namespace:LeftClickContextMenu.Enabled="True" />
Run Code Online (Sandbox Code Playgroud)
此技术称为附加行为,您可以在此代码项目文章中阅读更多相关信息:http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx
我刚刚根据HK1的答案编写并测试了这个(您还可以阅读附加属性概述中的附加属性):
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
...
<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>
Run Code Online (Sandbox Code Playgroud)
(注意OnMouseLeftButtonUp()方法中的注释)
| 归档时间: |
|
| 查看次数: |
7696 次 |
| 最近记录: |