MouseBinding鼠标滚轮在WPF和MVVM放大
-
20-09-2019 - |
题
OK,我已经找到了如何让我的UI元素的网格放大,通过使用LayoutTransform和ScaleTransform。我不明白的是我如何才能让我的查看响应CTRL + MouseWheelUp \下做到这一点,以及如何适应代码到MVVM模式。
我的第一个想法是将ZoomFactor存储为属性,并结合到一个命令以调整它。
我一直在寻找这样的:
<UserControl.InputBindings>
<MouseBinding Command="{Binding ZoomGrid}" Gesture="Control+WheelClick"/>
</UserControl.InputBindings>
,但我看到2个问题:
1),我不认为有一种方式告诉车轮是否被向上或向下移动,我也可以看到有多少来确定。我见过MouseWheelEventArgs.Delta,但不知道如何得到它。
2)绑定到该视图模型的命令看起来不正确,因为它是严格意义上的景观的事情。
由于变焦严格UI仅查看,我认为实际的代码应该在代码隐藏去了。
如何将你们实现这个?
P.S。,我使用.NET \ WPF 4.0使用束带为MVVM。
解决方案
我会建议你实现你的虚拟机的通用缩放命令。该命令可以用新的缩放级别进行参数设置,或(甚至简单),你可以实施的 IncreaseZoomCommand 和 DecreaseZoomCommand 的。然后使用视图的代码隐藏已处理的鼠标滚轮事件的事件参数之后调用这些命令。如果增量为正,放大,如果负缩小。
有在通过使用几行代码后面解决该问题的任何伤害。 MVVM的主要思想是,你可以跟踪和修改的对象不依赖于UI几乎视图的完整状态(增强了可测试性)。其结果是,新的视口的计算,其是变焦的结果应在VM和未在后面的代码来进行。
这在代码中存在可测性背后的小的间隙可以被忽略或由自动UI测试覆盖。自动UI测试,但是,可以是非常昂贵的。
其他提示
实际anwser是写自己的MouseGesture,这是很容易。
<MouseBinding Gesture="{x:Static me:MouseWheelGesture.CtrlDown}"
Command="me:MainVM.SendBackwardCommand" />
public class MouseWheelGesture : MouseGesture
{
public static MouseWheelGesture CtrlDown
=> new MouseWheelGesture(ModifierKeys.Control) { Direction = WheelDirection.Down
public MouseWheelGesture(): base(MouseAction.WheelClick)
{
}
public MouseWheelGesture(ModifierKeys modifiers) : base(MouseAction.WheelClick, modifiers)
{
}
public WheelDirection Direction { get; set; }
public override bool Matches(object targetElement, InputEventArgs inputEventArgs)
{
if (!base.Matches(targetElement, inputEventArgs)) return false;
if (!(inputEventArgs is MouseWheelEventArgs args)) return false;
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,
}
}
如果你不想使用后面的代码,你可以使用MVVM光EventToCommand功能:
查看:
<...
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>
视图模型:
ZoomCommand = new RelayCommand<RoutedEventArgs>(Zoom);
...
public void Zoom(RoutedEventArgs e)
{
var originalEventArgs = e as MouseWheelEventArgs;
// originalEventArgs.Delta contains the relevant value
}
我希望这可以帮助别人。我知道这个问题是慈祥的老人......
我想你试图做的是有很大关系的看法所以在把代码后面的代码(在我看来至少)没有坏处,但我敢肯定有处理这种这种优雅的方式它是基于多视图模型。
您应该能够注册到OnPrevewMouseWheel事件,检查用户已经按下控制键,并相应地改变你的缩放比例,让你正在寻找的变焦效果。
我同意这两个答案,只会增加,要使用的代码背后,是在这种情况下,唯一的办法,所以你甚至不必去想,如果它打破任何好的做法或没有。
事实是,得到MouseEventArgs(从而三角洲)的保持是在后面的代码,因此,抓住你需要什么就有什么(不需要为逻辑),并把它传递到您的视图模型作为奥利的唯一途径建议。
在另一面则可能要使用更通用的增量(例如,由120传递给它的一个步骤的视图模型之前将其划分),以保持它无知相关视图或OS的任何约定的。这将允许在视图模型代码的最大复用。
要避免整个问题,还有一个选项: -use在XAML一个ContentPresenter,让它的内容绑定到视图模型对象。 - 把手的视图模型内的滚轮的事件。