我有一个WPF应用程序..我在Xaml文件中有一个Image控件。
右键单击此图像,我有一个上下文菜单。
我想在“左键单击”中也显示相同内容。
我如何以MVVM的方式做到这一点?
答案 0 :(得分:38)
这是一个仅限XAML的解决方案。 只需将此样式添加到按钮即可。 这将导致左右键单击打开上下文菜单。享受!
<Button Content="Open Context Menu">
<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>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem />
<MenuItem />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
答案 1 :(得分:11)
您可以使用像这样的图像
的MouseDown事件来完成此操作<Image ... MouseDown="Image_MouseDown">
<Image.ContextMenu>
<ContextMenu>
<MenuItem .../>
<MenuItem .../>
</ContextMenu>
</Image.ContextMenu>
</Image>
然后在代码隐藏
中的EventHandler中显示ContextMenuprivate void Image_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
Image image = sender as Image;
ContextMenu contextMenu = image.ContextMenu;
contextMenu.PlacementTarget = image;
contextMenu.IsOpen = true;
}
}
答案 2 :(得分:7)
您可以创建自己的DependencyProperty,在单击图像时打开上下文菜单,如下所示:
<Image Source="..." local:ClickOpensContextMenuBehavior.Enabled="True">
<Image.ContextMenu>...
</Image.ContextMenu>
</Image>
这是该属性的C#代码:
public class ClickOpensContextMenuBehavior
{
private static readonly DependencyProperty ClickOpensContextMenuProperty =
DependencyProperty.RegisterAttached(
"Enabled", typeof(bool), typeof(ClickOpensContextMenuBehavior),
new PropertyMetadata(new PropertyChangedCallback(HandlePropertyChanged))
);
public static bool GetEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(ClickOpensContextMenuProperty);
}
public static void SetEnabled(DependencyObject obj, bool value)
{
obj.SetValue(ClickOpensContextMenuProperty, value);
}
private static void HandlePropertyChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (obj is Image) {
var image = obj as Image;
image.MouseLeftButtonDown -= ExecuteMouseDown;
image.MouseLeftButtonDown += ExecuteMouseDown;
}
if (obj is Hyperlink) {
var hyperlink = obj as Hyperlink;
hyperlink.Click -= ExecuteClick;
hyperlink.Click += ExecuteClick;
}
}
private static void ExecuteMouseDown(object sender, MouseEventArgs args)
{
DependencyObject obj = sender as DependencyObject;
bool enabled = (bool)obj.GetValue(ClickOpensContextMenuProperty);
if (enabled) {
if (sender is Image) {
var image = (Image)sender;
if (image.ContextMenu != null)
image.ContextMenu.IsOpen = true;
}
}
}
private static void ExecuteClick(object sender, RoutedEventArgs args)
{
DependencyObject obj = sender as DependencyObject;
bool enabled = (bool)obj.GetValue(ClickOpensContextMenuProperty);
if (enabled) {
if (sender is Hyperlink) {
var hyperlink = (Hyperlink)sender;
if(hyperlink.ContextMenu != null)
hyperlink.ContextMenu.IsOpen = true;
}
}
}
}
答案 3 :(得分:3)
您只需要将代码添加到函数Image_MouseDown
中e.Handled = true;
然后它不会消失。
答案 4 :(得分:0)
如果您只想在Xaml中执行此操作而不使用代码隐藏,则可以使用Expression Blend的触发器支持:
...
xmlns:i="schemas.microsoft.com/expression/2010/interactivity"
...
<Button x:Name="addButton">
<Button.ContextMenu>
<ContextMenu ItemsSource="{Binding Items}" />
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:ChangePropertyAction TargetObject="{Binding ContextMenu, ElementName=addButton}" PropertyName="PlacementTarget" Value="{Binding ElementName=addButton, Mode=OneWay}"/>
<ei:ChangePropertyAction TargetObject="{Binding ContextMenu, ElementName=addButton}" PropertyName="IsOpen" Value="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button.ContextMenu>
</Button>
答案 5 :(得分:0)
您可以将contextMenu的Isopen属性绑定到viewModel中的属性,如“IsContextMenuOpen”。 但问题是你不能直接将contextmenu绑定到你的viewModel,因为它不是你的userControl hiarchy的一部分。所以要解决这个问题你应该把tag属性绑定到你视图的dataontext。
<Image Tag="{Binding DataContext, ElementName=YourUserControlName}">
<ContextMenu IsOpen="{Binding PlacementTarget.Tag.IsContextMenuOpen,Mode=OneWay}" >
.....
</ContextMenu>
<Image>
祝你好运。
答案 6 :(得分:0)
嘿,我遇到了同样的问题,寻找一个我在这里找不到的解决方案。
我对MVVM一无所知,所以它可能不符合MVVM,但它对我有用。
第1步:为您的上下文菜单命名。
UIColor.clearColor()
步骤2:双击控件对象并插入此代码。订单很重要!
<Button.ContextMenu>
<ContextMenu Name="cmTabs"/>
</Button.ContextMenu>
第3步:享受
这将对左和右做出反应右键点击。它是带有ControlTemplate的ImageBrush的按钮。
答案 7 :(得分:-1)
XAML
<Button x:Name="b" Content="button" Click="b_Click" >
<Button.ContextMenu >
<ContextMenu >
<MenuItem Header="Open" Command="{Binding OnOpen}" ></MenuItem>
<MenuItem Header="Close" Command="{Binding OnClose}"></MenuItem>
</ContextMenu>
</Button.ContextMenu>
</Button>
C#
private void be_Click(object sender, RoutedEventArgs e)
{
b.ContextMenu.DataContext = b.DataContext;
b.ContextMenu.IsOpen = true;
}