我有一个WPF应用程序中旋转Compass UX元素的工作原型。我有后面的代码和数学计算捕获鼠标,并用鼠标向下旋转指南针,以便北始终跟随鼠标位置。这是一个独立的UserControl对象,我在主Xaml页面中声明,我插入了我需要的各种事件。 This post是我执行代码的方法,而this是我如何绑定Angle属性所以我可以让app逻辑设置值而不需要在控件上直接输入。
最近,我开始将我的原型移植到生产仓库中,该仓库被组织成一个MVVM模式。我将简单的点击事件连接到正确的命令,但是现在UX在新的生产项目中不会旋转。执行控制台打印显示我的鼠标正在被捕获,并且代码隐藏达到了我想要应用于UX的确切预期角度,但它没有改变。
我尝试了几种替代方法,但没有任何方法可以再次获得我原来的行为。最初,我尝试在我的ViewModel中声明依赖属性,没有任何更改。我也尝试过创建RotateTransform并直接设置控件的RenderTransform,但这会产生一种非常不稳定的行为(但它确实会开始旋转!)
连接到MainViewModel并设置TwoWay绑定对我的MVVM项目来说是新的,注释掉的行就是我在原型中的工作绑定。
<Image x:Name="Compass" RenderTransformOrigin="0.5,0.5" >
<Image.DataContext>
<p:MainViewModel/>
</Image.DataContext>
<Image.RenderTransform>
<RotateTransform Angle="{Binding BearingAngle, Mode=TwoWay}"/>
<!--RotateTransform Angle="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type p:CompassView}}, Path=Angle}"/-->
</Image.RenderTransform>
</Image>
其背后的代码具有以下DependencyProperty。
public static readonly DependencyProperty AngleProperty =
DependencyProperty.Register("Angle", typeof(double), typeof(CompassControl), new UIPropertyMetadata(0.0));
public double Angle
{
get { return (double)GetValue(AngleProperty); }
set { SetValue(AngleProperty, value); }
}
我必须在MVVM项目中获得最接近的移动设置如下变换(注意,这会导致我的旋转以一个看似随机的角度闪烁90-180度异相,没有跟随光标的任何模式):
this.RenderTransform = new RotateTransform(this.Angle, knobCenter.X, knobCenter.Y);
最终,作为MVVM组织的生产回购可能是一个红色的鲱鱼,我忽略了其他的东西,但由于我对MVVM应该如何工作相对缺乏经验,这是我唯一的迹象表明它为什么不在这个项目中工作但是在原型演示中很好。
更新:事实证明我的问题与所有这一切无关。创建我的Compass的父控件使用自定义Image类型覆盖了Image属性(以及它的RenderTransform),导致我试图操作的RenderTransform是不正确的。我声明我的Compass属于这种自定义类型,并删除了父控件中的覆盖代码,一切都按预期再次运行。由于此父控件对我的自定义命令执行了所有绑定而没有任何直接引用DataContext或ViewModel,因此具有简单绑定足以让所有内容在我需要的地方看到彼此。我相信我试图以一种“简单”的应用程序强制一些绑定方式,而不是完全利用ViewModel自然传播的方式抛出控件,从而得到了奇怪的行为。
问题很可能是由于在DataContext
上设置了Image
。你在那里做的方式,将创建一个MainViewModel
类的新实例,这可能不是你想要的。通常,DataContext
设置在Window
或UserControl
水平,并允许“流动”通过对照。
您最有可能需要将DataContext
绑定到属性,而不是创建新属性。
如果您要发布更多控件及其主视图模型,我们可以进一步帮助您。
如果我现在必须猜测,从您当前的代码,正确的绑定可能看起来像:
<Image x:Name="Compass"
RenderTransformOrigin="0.5,0.5"
DataContext={Binding Path=SomeCompassViewModelPropertyOnYourMainViewModel" >