I have a working prototype for a rotating Compass UX element in a WPF app. I have the code behind and math worked out to capture the mouse, and rotate the compass with the mouse down so that North always follows the mouse position. This is a standalone UserControl object that I declare in the main Xaml page where I plug into various events I need. This post is how I did the code behind, and this is how I bound the Angle property so I could have the app logic set the value without any direct input on the control.
Recently, I've started porting my prototype into the production repo which is organized into an MVVM pattern. I have the simple click events wired up to the right commands, but the UX does not rotate now that it is in the new, production project. Doing a console print shows that my mouse is being captured, and the codebehind is reaching the exact, expected angle I want applied to the UX, but it does not change.
I have tried a couple alternative approaches, but nothing is getting my original behavior again. Initially, I tried declaring the dependancy property in my ViewModel, with no change. I have also tried creating the RotateTransform and directly setting the control's RenderTransform, but this creates a very erratic behavior (but it does start rotating!)
Connecting to the MainViewModel and setting TwoWay binding is new to my MVVM project, with the commented out line being how I have the working binding in my prototype.
<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>
The code behind that works has the following 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); }
}
The closest I have to getting any movement in the MVVM project sets the transform as follows (NOTE, this causes my rotation to flicker 90-180 degrees out of phase with a seemingly random angle, does not have any pattern to following the cursor):
this.RenderTransform = new RotateTransform(this.Angle, knobCenter.X, knobCenter.Y);
Ultimately, the production repo being organized as MVVM might be a red herring and I'm overlooking something else, but since I am relatively inexperienced with how MVVM is supposed to work, that's my only indication of why it's not working in this project but is fine in a prototype demo.
UPDATE: Turns out my problem was unrelated to all of this. A parent control that created my Compass was overwriting the Image property (along with it's RenderTransform) with a custom Image type, causing the RenderTransform I was trying to manipulate be the incorrect one. I declared my Compass to be of this custom type, and removed the overwriting code in the parent control, and everything was working again as expected. Since this parent control did all the binding for my custom Commands without any direct reference to the DataContext or ViewModel, having the simple binding was enough for everything to see each other from where I needed them. I believe I was getting weird behavior from trying to force some bindings the way I had to in a "simple" app vs fully leveraging the way the ViewModel naturally propagates down throw the controls.