2010-02-16 11 views
8

OK, he descubierto cómo hacer que mi Cuadrícula de elementos de la interfaz de usuario se acerque, utilizando LayoutTransform y ScaleTransform. Lo que no entiendo es cómo puedo hacer que mi Vista responda CTRL + MouseWheelUp \ Down para hacerlo, y cómo ajustar el código en el patrón de MVVM.RatónEnlazando la rueda del mouse para ampliar WPF y MVVM

Mi primera idea fue almacenar el ZoomFactor como una propiedad, y vincularlo a un comando para ajustarlo.

que estaba viendo algo como:

<UserControl.InputBindings> 
<MouseBinding Command="{Binding ZoomGrid}" Gesture="Control+WheelClick"/> 
</UserControl.InputBindings> 

pero veo 2 números:

1) Creo que no hay una manera de saber si la rueda se mueve hacia arriba o hacia abajo, tampoco puedo ver cómo determinar cuánto. He visto MouseWheelEventArgs.Delta, pero no tengo idea de cómo conseguirlo.

2) Enlazar a un comando en el modelo de vista no parece correcto, ya que es estrictamente una cosa de Vista.

Dado que el zoom es estrictamente solo UI View, creo que el código real debe ir en el código subyacente.

¿Cómo podrían implementar esto?

p.s., estoy usando .net \ wpf 4.0 usando Cinch para MVVM.

+0

Encontrado esto en la web, puede ser que pueda ayudar ... http://social.technet.microsoft.com/wiki/contents/articles/18199.event-handling-in-an-mvvm-wpf-application .aspx – dunamis

Respuesta

5

Le sugiero que implemente un comando de zoom genérico en su máquina virtual. El comando se puede parametrizar con un nuevo nivel de zoom, o (quizás incluso más simple) puede implementar un IncreaseZoomCommand y DecreaseZoomCommand. A continuación, utilice el código de la vista para llamar a estos comandos después de haber procesado los argumentos de evento del evento Mouse Wheel. Si el delta es positivo, amplía, si el zoom se aleja negativamente.

No hay problema en resolver este problema usando algunas líneas de código. La idea principal de MVVM es que puede rastrear y modificar casi el estado completo de su vista en un objeto que no depende de la interfaz de usuario (mejora la capacidad de prueba). En consecuencia, el cálculo de la nueva ventana gráfica que es el resultado del zoom se debe hacer en la VM y no en el código subyacente.

La pequeña brecha de capacidad de prueba que existe en el código subyacente puede ser ignorada o cubierta por pruebas automáticas de UI. Las pruebas de IU automáticas, sin embargo, pueden ser muy costosas.

0

Creo que lo que intentas hacer está muy relacionado con la vista, así que no hay nada de malo en poner código en tu código (al menos en mi opinión), aunque estoy seguro de que hay maneras elegantes de manejarlo. tal que es más basado en el modelo de vista.

Debe poder registrarse en el evento OnPrevewMouseWheel, comprobar si el usuario tiene presionada la tecla de control y cambiar su factor de zoom en consecuencia para obtener el efecto de zoom que está buscando.

0

Estoy de acuerdo con ambas respuestas, y solo agregaría que utilizar el código subyacente es la única forma en este caso, por lo que ni siquiera tiene que pensar si infringe alguna de las buenas prácticas o no.

De hecho, la única forma de obtener los MouseEventArgs (y por lo tanto el Delta) está en el código subyacente, así que tome lo que necesite allí (no necesita lógica) y páselo a su modelo de vista como olli sugirió.

Por otro lado, es posible que desee utilizar un delta más genérico (por ejemplo, divídalo por 120 antes de pasarlo como un paso al modelo de vista) con el fin de mantenerlo ignorante de las convenciones relacionadas con la vista o el OS. Esto permitirá la reutilización máxima de su código en el modelo de vista.

1

Si no desea usar código subyacente puede utilizar la funcionalidad de la luz EventToCommand MVVM:

Vista:

<... 
    xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4" 
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    ...> 
<i:Interaction.Triggers> 
     <i:EventTrigger EventName="PreviewMouseWheel"> 
      <cmd:EventToCommand Command="{Binding 
    Path=DataContext.ZoomCommand, 
    ElementName=Root, Mode=OneWay}" 
     PassEventArgsToCommand="True" /> 
     </i:EventTrigger> </i:Interaction.Triggers> 

modelo de vista:

ZoomCommand = new RelayCommand<RoutedEventArgs>(Zoom); 
... 
public void Zoom(RoutedEventArgs e) 
{ 
    var originalEventArgs = e as MouseWheelEventArgs; 
    // originalEventArgs.Delta contains the relevant value 
} 

Espero que esto ayude alguien. Sé que la pregunta es un poco antigua ...

+0

Me parece raro que tu VM tenga un evento enrutado – Alan

8

el verdadero producto es escribir tu propia MouseGesture, que es fácil.

<MouseBinding Gesture="{x:Static me:MouseWheelGesture.CtrlDown}" 
       Command="me:MainVM.SendBackwardCommand" /> 






public class MouseWheelGesture : MouseGesture 
    { 
    public WheelDirection Direction { get; set; } 


    public static MouseWheelGesture CtrlDown 
    { 
     get 
     { 
     return new MouseWheelGesture(ModifierKeys.Control) { Direction = WheelDirection.Down }; 
     } 
    } 


    public MouseWheelGesture(): base(MouseAction.WheelClick) 
    { 
    } 

    public MouseWheelGesture(ModifierKeys modifiers) : base(MouseAction.WheelClick, modifiers) 
    { 
    } 



    public override bool Matches(object targetElement, InputEventArgs inputEventArgs) 
    { 
     if (!base.Matches(targetElement, inputEventArgs)) return false; 
     if (!(inputEventArgs is MouseWheelEventArgs)) return false; 
     var args = (MouseWheelEventArgs)inputEventArgs; 
     switch (Direction) 
     { 
     case WheelDirection.None: 
      return args.Delta == 0; 
     case WheelDirection.Up: 
      return args.Delta > 0; 
     case WheelDirection.Down: 
      return args.Delta < 0; 
     default: 
      return false; 
     } 
    } 



    public enum WheelDirection 
    { 
     None, 
     Up, 
     Down, 
    } 

    } 
0

Para evitar el problema, no es una opción más: -uso un ContentPresenter en el XAML y dejar que su contenido puede unir a un objeto modelo de vista. -handle los eventos de mouse en el viewmodel.

Cuestiones relacionadas