webentwicklung-frage-antwort-db.com.de

WPF Kontextmenü bei Linksklick

Ich habe eine WPF-Anwendung, in der ich ein Bildsteuerelement in der Xaml-Datei habe.

Beim Rechtsklick auf dieses Bild habe ich ein Kontextmenü. 

Ich möchte dasselbe auf "Linksklick" angezeigt werden.

Wie mache ich das auf MVVM-Art?

23
Relativity

Hier ist eine Lösung, die nur für XAML geeignet ist. Fügen Sie diesen Stil einfach Ihrer Schaltfläche hinzu. Dadurch wird das Kontextmenü mit einem Links- und Rechtsklick geöffnet. Genießen!

<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>
38
Ben Wilde

Sie können dies tun, indem Sie das MouseDown-Ereignis eines solchen Bildes verwenden

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

Und dann zeigen Sie das ContextMenu im EventHandler im Code hinter

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;
    }
}
11
Fredrik Hedblad

Sie können Ihre eigene DependencyProperty erfinden, die beim Klicken auf ein Bild ein Kontextmenü öffnet.

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

Und hier ist ein C # -Code für diese Eigenschaft:

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

sie müssen nur den Code in die Funktion Image_MouseDown einfügen

e.Handled = true;

Dann wird es nicht verschwinden.

3
Bruce Wu

sie können die Isopen-Eigenschaft des contextMenu an eine Eigenschaft in Ihrem viewModel wie "IsContextMenuOpen" ..__ binden. Das Problem ist jedoch, dass Sie das Kontextmenü nicht direkt an Ihr viewModel binden können, da es nicht Bestandteil von userControl hiarchy.So ist Beheben Sie dieses Problem. Sie sollten die Tag-Eigenschaft an den Datentext Ihrer Ansicht anpassen.

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

Viel Glück.

0
erradi mourad

Wenn Sie dies nur in Xaml tun möchten, ohne Code-Behind zu verwenden, können Sie die Auslöserunterstützung von Expression Blend verwenden:

...
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
Flatliner DOA

Hey, ich bin auf das gleiche Problem gestoßen, als ich nach einer Lösung gesucht habe, die ich hier nicht gefunden habe.

Ich weiß nichts über MVVM, also ist es wahrscheinlich nicht MVVM-konform, aber es hat für mich funktioniert.

Schritt 1: Geben Sie Ihrem Kontextmenü einen Namen.

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

Schritt 2: Doppelklicken Sie auf das Steuerelement und fügen Sie diesen Code ein. Bestellung zählt!

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

Schritt 3: Genießen Sie es

Dies wird für Links- und Rechtsklick reagieren. Es ist eine Schaltfläche mit einem ImageBrush mit einer ControlTemplate.

0
Matthis Kohli