WPF Context menu on left click

后端 未结 8 484
情深已故
情深已故 2020-12-01 10:39

I have a WPF application..In which I have an Image control in Xaml file.

On right click of this image I have a context menu.

I would like to have same to be

相关标签:
8条回答
  • 2020-12-01 10:59

    Hey I came across the same problem looking for a solution which I didn't find here.

    I don't know anything about MVVM so it's probably not MVVM conform but it worked for me.

    Step 1: Give your context menu a name.

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

    Step 2: Double click the control object and insert this code. Order matters!

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

    Step 3: Enjoy

    This will react for left & right click. It's a button with a ImageBrush with a ControlTemplate.

    0 讨论(0)
  • 2020-12-01 11:00

    You can invent your own DependencyProperty which opens a context menu when image is clicked, just like this:

      <Image Source="..." local:ClickOpensContextMenuBehavior.Enabled="True">
          <Image.ContextMenu>...
          </Image.ContextMenu>
      </Image>
    

    And here is a C# code for that property:

    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;
          }
        }
      } 
    }
    
    0 讨论(0)
  • 2020-12-01 11:04

    If you want to do this just in Xaml without using code-behind you can use Expression Blend's triggers support:

    ...
    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>
    
    0 讨论(0)
  • 2020-12-01 11:06

    Here is a XAML only solution. Just add this style to your button. This will cause the context menu to open on both left and right click. Enjoy!

    <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>
    
    0 讨论(0)
  • 2020-12-01 11:08

    you only need add the code into function Image_MouseDown

    e.Handled = true;

    Then it will not disappear.

    0 讨论(0)
  • 2020-12-01 11:16

    You can do this by using the MouseDown event of an Image like this

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

    And then show the ContextMenu in the EventHandler in code behind

    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;
        }
    }
    
    0 讨论(0)
提交回复
热议问题