左键单击时的WPF上下文菜单

uqcuzwp8  于 2023-03-04  发布在  其他
关注(0)|答案(9)|浏览(222)

我有一个WPF应用程序..其中我有一个XAML文件中的图像控件。
右键单击此图像,我有一个上下文菜单.
我想有相同的显示在“左击”也。
如何以MVVM方式执行此操作?

q1qsirdb

q1qsirdb1#

这里是一个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>
dgjrabp2

dgjrabp22#

您可以通过使用Image的MouseDown事件来完成此操作,如下所示

<Image ... MouseDown="Image_MouseDown">
    <Image.ContextMenu>
        <ContextMenu>
            <MenuItem .../>
            <MenuItem .../>
        </ContextMenu>
    </Image.ContextMenu>
</Image>

然后在后台代码中显示EventHandler中的ContextMenu

private 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;
        e.Handled = true;
    }
}
bwntbbo3

bwntbbo33#

您可以创建自己的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;
      }
    }
  } 
}
djp7away

djp7away4#

如果你只想在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>
w51jfk4q

w51jfk4q5#

只需将代码添加到函数Image_MouseDown中
e.已处理=真;
它就不会消失。

dm7nw8vv

dm7nw8vv6#

嘿,我遇到了同样的问题,寻找一个解决方案,我没有在这里找到。
我对MVVM一无所知,所以它可能不符合MVVM,但它对我有效。
步骤1:给予上下文菜单命名。

<Button.ContextMenu>
    <ContextMenu Name="cmTabs"/>
</Button.ContextMenu>

第二步:双击控件对象,插入代码,顺序很重要!

Private Sub Button_Click_1(sender As Object, e As Windows.RoutedEventArgs)
        cmTabs.StaysOpen = True
        cmTabs.IsOpen = True
    End Sub

第三步:享受
这将对左右点击作出React。这是一个带有图像画笔和控件模板的按钮。

ao218c7q

ao218c7q7#

你可以将contextMenu的Isopen属性绑定到你的viewModel中的一个属性,比如"IsContextMenuOpen"。但是问题是你不能直接将contextMenu绑定到你的viewModel,因为它不是你的userControl层次结构的一部分。所以要解决这个问题,你应该将tag属性绑定到你的视图的dataontext。

<Image Tag="{Binding DataContext, ElementName=YourUserControlName}">
<ContextMenu IsOpen="{Binding PlacementTarget.Tag.IsContextMenuOpen,Mode=OneWay}" >
.....
</ContextMenu>
<Image>

祝你好运。

weylhg0b

weylhg0b8#

交互性已经过时,不再支持,新的实现方式是:

xmlns:b="http://schemas.microsoft.com/xaml/behaviors"

 <Button x:Name="ConvertVideoButton">
            <Button.ContextMenu>
                <ContextMenu VerticalContentAlignment="Top" >
                    <MenuItem Header="Convert  1"  Command="{Binding ConvertMkvCommand}" />
                    <MenuItem Header="Convert 2"  Command="{Binding ConvertMkvCommand}" />
                </ContextMenu>
            </Button.ContextMenu>

            <b:Interaction.Triggers>
                <b:EventTrigger  EventName="Click">
                    <b:ChangePropertyAction TargetObject="{Binding ContextMenu, ElementName=ConvertVideoButton}" PropertyName="PlacementTarget" Value="{Binding ElementName=ConvertVideoButton, Mode=OneWay}"/>
                    <b:ChangePropertyAction TargetObject="{Binding ContextMenu, ElementName=ConvertVideoButton}" PropertyName="IsOpen" Value="True"/>
                </b:EventTrigger>
            </b:Interaction.Triggers>
        </Button>
zbdgwd5y

zbdgwd5y9#

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;            
        }

相关问题