Silverlight 3 - Rotating a rectangle around an ellipse
I have a Silverlight user control that looks like a compass. I would post the image but i'm a new user and can't post images yet. :(.
Essentially think of a an outer ellipse and on the inside is an inner ellipse in the center w/ a rectangle serving as the 'hand' of the compass. I posted the xaml below.
I want to move the compass 'hand' when the left mouse button is down and the mouse is moved. I thought this would be relatively easy using a RotateTransform but I can't figure it out.
The problems I am running into are
A. I can't figure out how to set the CenterX,CenterY and Angle properties of my RotationTransform. I want the hand (the red rectangle) to rotate around the center ellipse (the brown ellipse in the middle).
B. Is their a way to slow down the rotationtransform? So if someone is spinning the mouse quickly the hand moves but not as fast as the user is moving the mouse. Stated another way is their a way to decrease the sensitivity of the mouse movement开发者_Go百科?
I would post my code but it is pretty sad. :-). I don't need an exact solution just a nudge in the right direction.
Here is the XAML
<Grid Margin="20,20,0,18" HorizontalAlignment="Left" Width="180">
<Ellipse x:Name="outerEllipse" Stroke="Black">
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
<GradientStop Color="#3FF7F5F5" Offset="0.449"/>
<GradientStop Color="#FFF7F1F1" Offset="0.938"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse x:Name="innerEllipse" Margin="16,14,16,13" Stroke="Black">
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFD8BABA" Offset="0"/>
<GradientStop Color="#FFF7F1F1" Offset="1"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse x:Name="knobEllipse" Margin="83,75,82,74" Stroke="Black" Fill="#FFCFB53B"/>
<TextBlock x:Name="textNorth" Height="17" Margin="83,14,83,0" TextWrapping="Wrap" Text="N" VerticalAlignment="Top" Foreground="#FFCC3131" FontSize="16" FontFamily="Book Antiqua"/>
<TextBlock x:Name="textNorthEast" Height="21" Margin="0,34,25.666,0" TextWrapping="Wrap" Text="NE" VerticalAlignment="Top" Foreground="#FFCC3131" FontSize="16" FontFamily="Book Antiqua" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" d:LayoutRounding="Auto" HorizontalAlignment="Right" Width="30">
<TextBlock.RenderTransform>
<CompositeTransform Rotation="45"/>
</TextBlock.RenderTransform>
</TextBlock>
<TextBlock x:Name="textSouth" Height="17" Margin="86,0,85,13" TextWrapping="Wrap" Text="S" VerticalAlignment="Bottom" Foreground="#FFCC3131" FontSize="16" FontFamily="Book Antiqua"/>
<TextBlock x:Name="textNorthWest" Height="21" Margin="29,31,0,0" TextWrapping="Wrap" Text="NW" VerticalAlignment="Top" Foreground="#FFCC3131" FontSize="16" FontFamily="Book Antiqua" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" d:LayoutRounding="Auto" HorizontalAlignment="Left" Width="30">
<TextBlock.RenderTransform>
<CompositeTransform Rotation="315"/>
</TextBlock.RenderTransform>
</TextBlock>
<TextBlock x:Name="textEast" HorizontalAlignment="Right" Margin="0,75,16,74" TextWrapping="Wrap" Text="E" Width="11" Foreground="#FFCC3131" FontSize="16" FontFamily="Book Antiqua"/>
<TextBlock x:Name="textWest" HorizontalAlignment="Left" Margin="16,73,0,72" TextWrapping="Wrap" Text="W" Width="20" Foreground="#FFCC3131" FontSize="16" FontFamily="Book Antiqua"/>
<TextBlock x:Name="textSouthEast" Margin="0,0,33.834,25.333" TextWrapping="Wrap" Text="SE" Foreground="#FFCC3131" FontSize="16" FontFamily="Book Antiqua" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" d:LayoutRounding="Auto" HorizontalAlignment="Right" Height="21" VerticalAlignment="Bottom" Width="30">
<TextBlock.RenderTransform>
<CompositeTransform Rotation="140"/>
</TextBlock.RenderTransform>
</TextBlock>
<TextBlock x:Name="textSouthWest" Margin="31.5,0,0,29.5" TextWrapping="Wrap" Text="SW" Foreground="#FFCC3131" FontSize="16" FontFamily="Book Antiqua" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" d:LayoutRounding="Auto" HorizontalAlignment="Left" Width="30" Height="21" VerticalAlignment="Bottom">
<TextBlock.RenderTransform>
<CompositeTransform Rotation="220"/>
</TextBlock.RenderTransform>
</TextBlock>
<Rectangle x:Name="rectanglePointer" Height="32" Margin="87,43,86,0" Stroke="Black" VerticalAlignment="Top">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFF38989" Offset="0"/>
<GradientStop Color="#FF914949" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
Thanks for your help
By playing with your XAML, the following render transform origin will roughly produce what you are after:
<Rectangle x:Name="rectanglePointer" Height="32" Margin="87,43,86,0" Stroke="Black" VerticalAlignment="Top"
RenderTransformOrigin="0.5,2.8">
<Rectangle.RenderTransform>
<RotateTransform Angle="180"/>
</Rectangle.RenderTransform>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFF38989" Offset="0"/>
<GradientStop Color="#FF914949" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
The X offset of 0.5 moves rotation X position too be aligned with the centre of the rectangle, and the Y offset of 2.8 moves the rotation to centre roughly on the brown ellipse.
I say roughly, because the it is not easy to calculate based on your layout! Currently you are using margins to size everything, this means that the actual width of your rectangle is the width of your grid container, minus the left and right margin values. It is much better if you set the width / height explicitly.
Better still, use Grid columns / cells to create the layout you want. Take a look at this blog post:
http://www.scottlogic.co.uk/blog/colin/2010/08/developing-a-very-lookless-silverlight-radial-gauge-control/
You could probably adapt that control to your needs.
Slowing down the mouse movement, that could be tricky!
I would recommend changing your compass into a user control and making the compass angle a dependency property. Once you have a dependency property you can animate it from code-behind.
Hope that helps!
Colin E.
精彩评论