在图形密集型工程软件(CAD,FEM预/后处理(中以及游戏中,从输入来源解除视图的连续操纵动作非常普遍导致这些操纵。例如,2D或3D视图的旋转可以由任何
完成- ctrl-key weftmouse-rag
- 鼠标轮旋转
- 在UI中拖动滑块控件
- 在3D鼠标上推动轴,例如3DConnexion
在应用程序的设置中,可以自由地将操作"旋转视图"重新分配到这些鼠标输入操作之一,以便将应用程序的行为自定义为他的喜好(或可能与什么他习惯了其他应用程序(。
在WPF中有一种接受的方法,还是我必须提出自己的解决方案?
我已经考虑过命令,但是我想这并不适合,因为移动鼠标不是命令的触发因素。也许手势最接近,但似乎或多或少是为触摸输入而设计的。
我认为问题也可能是可能的复杂性:许多不同的键/鼠标/鼠标轴组合。甚至在某些情况下,按钮的顺序决定了视图操作(即Catia V5(。
我不知道在3D鼠标上推动轴的意思是什么。我现在正在编写WPF游戏套件,并且我使用MVVM以及用于鼠标的机制的组合。滑块控件只是拖动,您拖动的东西称为拇指。您可以将几乎所有内容放入WPF UI中的任何东西,而一种使某物可拖动的方法是将其放入拇指中。这就是您在设置方案时将单元拖动以定位它们的方式。
以下是场景编辑器项目中的一些标记。您可以通过将鼠标悬停在一块上并旋转鼠标轮来拖动这些并朝向更改。您还可以使用左键或右键单击CTRL 单击以在块中更改旋转角度。ViewModel更改了一个双面属性,该属性与旋转图上的角度结合。
<UserControl.CommandBindings>
<CommandBinding Command="local:CommandLibrary.LeftClick" Executed="LeftClick_Executed" />
<CommandBinding Command="local:CommandLibrary.RightClick" Executed="RightClick_Executed" />
</UserControl.CommandBindings>
<UserControl.InputBindings>
<MouseBinding Gesture="Shift+LeftClick"
Command="{Binding RotateCounterClockWiseCommand}"
CommandParameter="{StaticResource FortyFive}"/>
<MouseBinding Gesture="Shift+RightClick"
Command="{Binding RotateClockWiseCommand}"
CommandParameter="{StaticResource FortyFive}"/>
<!-- Up is away from user and Down is towards user -->
<MouseBinding Gesture="{local:MouseWheel Direction=Up}"
Command="{Binding RotateCounterClockWiseCommand}"
CommandParameter="{StaticResource Five}"/>
<MouseBinding Gesture="{local:MouseWheel Direction=Down}"
Command="{Binding RotateClockWiseCommand}"
CommandParameter="{StaticResource Five}"/>
<MouseBinding Gesture="LeftClick"
Command="local:CommandLibrary.LeftClick"
CommandTarget="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:PieceView}}}"
/>
<MouseBinding Gesture="RightClick"
Command="local:CommandLibrary.RightClick"
CommandTarget="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:PieceView}}}"
/>
</UserControl.InputBindings>
我要混合实现命令的方法是因为我使用点击是出于多种目的而直接的鼠标绑定不太喜欢。否则,我很少使用RoutedUiCommands。
鼠标车轮手势
public enum MouseWheelDirection { Up, Down }
public class MouseWheelGesture : MouseGesture
{
public MouseWheelDirection Direction { get; set; }
public MouseWheelGesture(ModifierKeys keys, MouseWheelDirection direction)
: base(MouseAction.WheelClick, keys)
{
Direction = direction;
}
public override bool Matches(object targetElement, InputEventArgs inputEventArgs)
{
var args = inputEventArgs as MouseWheelEventArgs;
if (args == null)
return false;
if (!base.Matches(targetElement, inputEventArgs))
return false;
if ( Direction == MouseWheelDirection.Up && args.Delta > 0
|| Direction == MouseWheelDirection.Down && args.Delta < 0)
{
inputEventArgs.Handled = true;
return true;
}
return false;
}
}
public class MouseWheel : MarkupExtension
{
public MouseWheelDirection Direction { get; set; }
public ModifierKeys Keys { get; set; }
public MouseWheel()
{
Keys = ModifierKeys.None;
Direction = MouseWheelDirection.Down;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return new MouseWheelGesture(Keys, Direction);
}
}
这是command of picevm:
private RelayCommand<Double> rotateClockWiseCommand;
public RelayCommand<Double> RotateClockWiseCommand
{
get
{
return rotateClockWiseCommand
?? (rotateClockWiseCommand = new RelayCommand<Double>(
(increase) =>
{
if(Facing + increase > 359)
{
Facing = 0;
}
else
{
Facing += increase;
}
}));
}
}
selayCommand来自mvvmlight。您可以使用nuget mvvmlightlibs。
每件(在板上(是带有PIECEVM的USERCONTROL,因为它的DataContext。实际的碎片是通过模板与一块相关联的模板来生成的。这是一种相当标准的ViewModel第一种方法。
这是旋转变换。
<UserControl.RenderTransform>
<RotateTransform Angle="{Binding Facing, FallbackValue=0, TargetNullValue=0}" />
</UserControl.RenderTransform>
一块实际上是圆形的,因为它的根是一个边界:
<Border CornerRadius="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}"
Width="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}"
Name="border"
BorderThickness="1.5"
>