Tengo una aplicación de WPF..En la que tengo un control de Imagen en el archivo Xaml.

A la derecha haga clic en la imagen, tengo un menú contextual.

Me gustaría tener el mismo se muestre en «clic Izquierdo» también.

¿Cómo puedo hacer esto en MVVM manera ?

  • Aunque es posible, sería en contra de la estándar de windows expectativas para mostrar el menú contextual haga clic a la izquierda.
  • Pero mi cliente necesita que
  • Con respecto a lo que esta MVVM, creo que el XAML sería en su «punto de vista», el Image_MouseDown código en C# que estar en tu «modelo», y su «modelo» no debe saber nada sobre el menú de contexto.
InformationsquelleAutor Relativity | 2010-11-29

8 Comentarios

  1. 39

    Aquí es un XAML única solución.
    Añadir estilo a su botón.
    Esto hará que el menú contextual para abrir en la derecha y a la izquierda haga clic en. ¡A disfrutar!

    <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>
    • No funciona propiedad para net35
    • El estilo de vino correcto, sin embargo, al añadir un Comando a la Entrada, no se activa el evento. He comprobado – los enlaces son correctos. Alguna idea?
    • Tengo el mismo problema con @utkarsh, cuando trato de unión comando para MenuItem, <MenuItem Header="Download" Command="{Binding DownloadButtonCommand}"/> no funciona, algún consejo?
    • Parece que el enlace de datos de la contextmenu sólo se establece en el botón derecho. Después de clic derecho-abrir primero se trabaja también en la izquierda haga clic en. Es por eso que terminé usando esta solución: stackoverflow.com/a/29123964/4550393
  2. 12

    Usted puede hacer esto mediante el evento MouseDown de una Imagen como esta

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

    Y, a continuación, mostrar el ContextMenu en el EventHandler en el código detrás de

    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;
        }
    }
    • Esta aplicación hace que el menú de contexto para aparecer y desaparecer de inmediato. Estoy usando el control y su menú de contexto en una plantilla de datos, no se si lo que importa…
    • esto no parece aumentar el ContextMenuOpening evento para el código de función en la que no se ejecute..
    • Veo el mismo como epalm
    • uxpassion.com/blog/old-blog/…
    • Sólo utilice evento MouseUp
    • Si vas a añadir esto a un Botón (no una Imagen) entonces sólo hay que poner un código similar a este en el interior de la Button_Click evento en sí.
    • Esto claramente no funciona
    • agregar e.Handled = true para hacer este trabajo

  3. 8

    Puede inventar su propia DependencyProperty que se abre un menú contextual cuando la imagen se hace clic, al igual que este:

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

    Y aquí es un código de C# para que la propiedad:

    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;
    }
    }
    } 
    }
    • Esto fue muy útil, pero yo necesitaba para asignar el PlacementTarget de la ContextMenu de vuelta a la DependencyObject (en mi caso, Button), para que el menú para rellenar correctamente. Esto era para un contexto dinámico menú pobladas para cada elemento en una ListView.
  4. 3

    sólo es necesario agregar el código en la función Image_MouseDown

    e.Handled = true;

    Entonces no va a desaparecer.

  5. 0

    Si quieres hacer esto solo en Xaml, sin el uso de código-detrás de usted puede usar Expression Blend disparadores de apoyo:

    ...
    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>
    • Podría usted especificar los espacios de nombres xml en tu ejemplo?
    • xmlns=»schemas.microsoft.com/winfx/2006/xaml/presentation» xmlns:i=»schemas.microsoft.com/expression/2010/interactivity«
    • Esto tiene el mismo problema epalm menciona en la otra respuesta
    • Mi problema con esta respuesta es que no hay un completo listado de código para «<ContextMenu ItemsSource=»{Binding Elementos}» />» no tiene sentido. También, si puedo conectarlo en un entorno limitado de la aplicación que tengo, me da errores con la sintaxis de todos modos. Estoy usando .Net4.5, VS2013, lo bastante seguro de que no es eso!
  6. 0

    puede enlazar el Isopen Propiedad de la contextMenu de una propiedad en su viewModel como «IsContextMenuOpen».
    pero el problema es que tu no se puede enlazar directamente el contextmenu a su viewModel porque no es una parte de su userControl hiarchy.Así que para resolver este debe bing la propiedad tag a la dataontext de su vista.

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

    Buena suerte.

  7. 0

    Hola me encontré con el mismo problema buscando una solución que no me encuentre aquí.

    No sé nada acerca de MVVM así que es probable que no MVVM conformarse, sino que trabajó para mí.

    Paso 1: dale a tu menú de contexto de un nombre.

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

    Paso 2: haga Doble clic en el objeto de control y de insertar este código. El orden importa!

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

    Paso 3: Disfrutar De

    Esto va a reaccionar a la izquierda & click derecho. Es un botón con un ImageBrush con una ControlTemplate.

  8. -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;            
    }
    • OP está preguntando acerca de un clickevent en un control de imagen. Usted está sirviendo a una solución para un control de botón.
    • Esto también no siga la buena mvvm prácticas.

Dejar respuesta

Please enter your comment!
Please enter your name here