I'm trying to create a popup that follows the mouse pointer while dragging a draggable item.
The following snipping opens the popup at the mouse pointer but I rely on the GiveFeedback delegate to allow me to update the popup location (that is, if the pointer moved)
private void Members_DragOver(object sender, DragEventArgs e)
{
dragPopup.DataContext = DraggedItem;
var mousePoint = Mouse.GetPosition(this);
dragPopup.HorizontalOffset = mousePoint.X + this.Left + 10;
dragPopup.VerticalOffset = mousePoint.Y + this.Top + 10;
dragPopup.IsOpen = true;
}
private void Members_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
if (dragPopup.IsOpen)
{
var mousePoint = Mouse.GetPosition(this);
dragPopup.HorizontalOffset = mousePoint.X + this.Left + 10;
dragPopup.VerticalOffset = mousePoint.Y + this.Top + 10;
dragPopup.IsOpen = true;
}
}
And the popup itself which resided in the main grid of my window.
NOTE
I've tried handling the position during the MouseMove or PreviewMouseMove, but these events are ignored completely during a drag-and-drop procedure.
<Popup x:Name="dragPopup" Placement="MousePoint">
<Border BorderThickness="2" Background="White" DataContext="{Binding}">
<StackPanel Orientation="Horizontal" Margin="4,3,8,3">
<TextBlock Text="{Binding FullName}" FontWeight="Bold" VerticalAlignment="Center" Margin="8,0,0,0" />
</StackPanel>
</Border>
</Popup>
The GiveFeedback delegate fires only once (setting a breakpoint with a hitcounter of 5 confirms this). Even though this MSDN article says:
This event is raised continuously during the drag-and-drop operation. Therefore, you should avoid resource-intensive tasks in the event handler. For example, use a cached cursor instead of creating a new cursor each time the GiveFeedback event is raised.
Why is the delegate fired only once?
You are right, GiveFeedBack is the way to do it.I did manage to get the GiveFeedBack to be called during drag. Apparently the mouse position in GiveFeedBack is handled different than in the mouse move. I manage to fix this by using the WinForms mouse position. Add reference System.Windows.Forms and System.Drawing for the following code:
Xaml:
<Grid GiveFeedback="Members_GiveFeedback">
<Popup x:Name="dragPopup" Placement="MousePoint">
<Border BorderThickness="2" Background="White" DataContext="{Binding}">
<StackPanel Orientation="Horizontal" Margin="4,3,8,3">
<TextBlock Text="Test" FontWeight="Bold" VerticalAlignment="Center" Margin="8,0,0,0" />
</StackPanel>
</Border>
</Popup>
<StackPanel Orientation="Horizontal">
<ListBox x:Name="sourcList" Height="50"
PreviewMouseLeftButtonDown="ListBox_PreviewMouseLeftButtonDown"
PreviewMouseMove="sourcList_PreviewMouseMove"
AllowDrop="True" >
<ListBoxItem > source Item #1</ListBoxItem>
</ListBox>
<ListBox x:Name="droplist" Height="50" AllowDrop="True" Drop="droplist_Drop" >
<ListBoxItem >dest Item #2</ListBoxItem>
</ListBox>
</StackPanel>
</Grid>
private void ListBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var mousePoint = Mouse.GetPosition(this);
startPoint=mousePoint;
var point = GetMousePositionWindowsForms();
var formsmousePoint = new Point(point.X, point.Y);
var pointfromscreen = dragPopup.PointFromScreen(formsmousePoint);
dragPopup.HorizontalOffset = pointfromscreen.X - 100;
dragPopup.VerticalOffset = pointfromscreen.Y - 100;
dragPopup.IsOpen = true;
}
private void sourcList_PreviewMouseMove(object sender, MouseEventArgs e)
{
...
}
private void droplist_Drop(object sender, DragEventArgs e)
{
...
}
private void Members_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
if (dragPopup.IsOpen)
{
var point=GetMousePositionWindowsForms();
var mousePoint = new Point(point.X, point.Y);
var pointfromscreen=dragPopup.PointFromScreen(mousePoint);
dragPopup.HorizontalOffset = pointfromscreen.X-100;
dragPopup.VerticalOffset = pointfromscreen.Y-100;
}
}
public static Point GetMousePositionWindowsForms()
{
System.Drawing.Point point = System.Windows.Forms.Control.MousePosition;
return new Point(point.X, point.Y);
}
I just got your popup following my mouse by doing the following:
private void ListBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var mousePoint = Mouse.GetPosition(this);
dragPopup.HorizontalOffset = mousePoint.X + this.Left + 10;
dragPopup.VerticalOffset = mousePoint.Y + this.Top + 10;
dragPopup.IsOpen = true;
}
private void Grid_MouseMove(object sender, MouseEventArgs e)
{
var mousePoint = Mouse.GetPosition(this);
dragPopup.HorizontalOffset = mousePoint.X + this.Left + 10;
dragPopup.VerticalOffset = mousePoint.Y + this.Top + 10;
}
Then on the xaml side
<Grid MouseMove="Grid_MouseMove">
...
<ListBox Height="50" PreviewMouseLeftButtonDown="ListBox_PreviewMouseLeftButtonDown" AllowDrop="True">
<ListBoxItem> ListBox Item #1</ListBoxItem>
</ListBox>
The position is a little off though.
private void UIElement_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
StartMousePosition = new System.Windows.Point(GetMousePositionWindowsForms().X, GetMousePositionWindowsForms().Y);
MoveDragInformationPopup();
DragInstrong textformationPopup.IsOpen = true;
}
private void UIElement_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
if (DragInformationPopup.IsOpen)
{
MoveDragInformationPopup();
}
}
private void MoveDragInformationPopup()
{
var point = GetMousePositionWindowsForms();
DragInformationPopup.HorizontalOffset = (point.X - StartMousePosition.X) + 5;
DragInformationPopup.VerticalOffset = (point.Y - StartMousePosition.Y) + 5;
}
private System.Drawing.Point GetMousePositionWindowsForms()
{
return System.Windows.Forms.Control.MousePosition;
}
Related
I have a slider which I want the thumb moves to exact position when click on anywhere on the slider track and moves slower when I press Shift key and drag the thumb. I know how to detect when the shift key is pressed but I don't know how to slow down the thumb. Any help would be appreciated!
Here is the xaml code:
<Grid>
<Slider x:Name="m_Slider" IsMoveToPointEnabled="True" Orientation="Vertical"
Height="200" Width="30" Minimum="0" Maximum="20" HorizontalAlignment="Center"
Thumb.DragStarted="Slider_ShiftDrag"/>
</Grid>
and here is the code-behind:
void Slider_ShiftDrag(object sender, DragStartedEventArgs e)
{
if (e != null && (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)))
{
//What should I do here?
}
}
I've written a fake slider to achieve your goal. I don't use the native Thumb because the native one captures the mouse and always follow the mouse. So I write a Rectangle instead of Thumb to do the dragging.
This is the XAML:
<Grid Width="400" Height="32">
<Rectangle x:Name="Tracker" Height="2" Fill="Gray" />
<Rectangle x:Name="Thumb" Width="8" Height="32" Margin="-4 -16" Fill="DarkGray" HorizontalAlignment="Left" VerticalAlignment="Center"
MouseDown="Thumb_MouseDown" MouseMove="Thumb_MouseMove" MouseUp="Thumb_MouseUp" LostMouseCapture="Thumb_LostMouseCapture">
<UIElement.RenderTransform>
<TranslateTransform x:Name="ThumbTranslation" />
</UIElement.RenderTransform>
</Rectangle>
</Grid>
And this is the code-behind:
private Point? _lastPoint;
private void Thumb_MouseDown(object sender, MouseButtonEventArgs e)
{
_lastPoint = e.GetPosition(Tracker);
Thumb.CaptureMouse();
}
private void Thumb_MouseMove(object sender, MouseEventArgs e)
{
if (_lastPoint != null)
{
var currentPoint = e.GetPosition(Tracker);
var offset = currentPoint - _lastPoint.Value;
_lastPoint = currentPoint;
if (Keyboard.Modifiers.HasFlag(ModifierKeys.Shift))
{
offset *= 0.2;
}
SetThumbTranslation(offset.X);
}
}
private void Thumb_MouseUp(object sender, MouseButtonEventArgs e)
{
_lastPoint = null;
Thumb.ReleaseMouseCapture();
}
private void Thumb_LostMouseCapture(object sender, MouseEventArgs e)
{
_lastPoint = null;
}
private void SetThumbTranslation(double offsetX)
{
var x = ThumbTranslation.X + offsetX;
x = Math.Max(x, 0);
x = Math.Min(x, Tracker.ActualWidth);
ThumbTranslation.X = x;
}
I have these three functions to trigger the events. I already have a static version of my needs, but I need a dynamically version of it.
bool captured = false;
double x_shape, x_canvas, y_shape, y_canvas;
UIElement source = null;
private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
source = (UIElement)sender;
Mouse.Capture(source);
captured = true;
x_shape = Canvas.GetLeft(source);
x_canvas = e.GetPosition(canvasPreview).X;
y_shape = Canvas.GetTop(source);
y_canvas = e.GetPosition(canvasPreview).Y;
}
private void MouseMove(object sender, MouseEventArgs e)
{
//MessageBox.Show("test");
if (captured)
{
double x = e.GetPosition(canvasPreview).X;
double y = e.GetPosition(canvasPreview).Y;
x_shape += x - x_canvas;
Canvas.SetLeft(source, x_shape);
x_canvas = x;
y_shape += y - y_canvas;
Canvas.SetTop(source, y_shape);
y_canvas = y;
}
}
private void MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Mouse.Capture(null);
captured = false;
}
I have made a canvas in WPF called 'canvasPreview', I want to add the rectangle (currently in the static version I am using an ellipse) to the canvas, it must be draggable with above functions. It is already working, but it have to be dynamically.
I hope you can help me, thank you in advance!
I'm sure this sample code will help you.
XAML:
<Grid Margin="12">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Button x:Name="addRectangleButton" Content="Add Rectngle" Click="addRectangleButton_Click"/>
</StackPanel>
<Canvas Grid.Row="1" x:Name="canvas" Margin="0,12,0,0">
<Rectangle x:Name="rectangle" Width="100" Height="50" Fill="RoyalBlue" MouseDown="rectangle_MouseDown" MouseMove="rectangle_MouseMove" MouseUp="rectangle_MouseUp" Canvas.Left="0" Canvas.Top="0"/>
</Canvas>
</Grid>
C#:
bool drag = false;
Point startPoint;
public MainWindow()
{
InitializeComponent();
}
// this creates and adds rectangles dynamically
private void addRectangleButton_Click(object sender, RoutedEventArgs e)
{
// create new Rectangle
Rectangle rectangle = new Rectangle();
// assign properties
rectangle.Width = 100;
rectangle.Height = 50;
rectangle.Fill = new SolidColorBrush(Colors.RoyalBlue);
// assign handlers
rectangle.MouseDown += rectangle_MouseDown;
rectangle.MouseMove += rectangle_MouseMove;
rectangle.MouseUp += rectangle_MouseUp;
// set default position
Canvas.SetLeft(rectangle, 0);
Canvas.SetTop(rectangle, 0);
// add it to canvas
canvas.Children.Add(rectangle);
}
private void rectangle_MouseDown(object sender, MouseButtonEventArgs e)
{
// start dragging
drag = true;
// save start point of dragging
startPoint = Mouse.GetPosition(canvas);
}
private void rectangle_MouseMove(object sender, MouseEventArgs e)
{
// if dragging, then adjust rectangle position based on mouse movement
if (drag)
{
Rectangle draggedRectangle = sender as Rectangle;
Point newPoint = Mouse.GetPosition(canvas);
double left = Canvas.GetLeft(draggedRectangle);
double top = Canvas.GetTop(draggedRectangle);
Canvas.SetLeft(draggedRectangle, left + (newPoint.X - startPoint.X));
Canvas.SetTop(draggedRectangle, top + (newPoint.Y - startPoint.Y));
startPoint = newPoint;
}
}
private void rectangle_MouseUp(object sender, MouseButtonEventArgs e)
{
// stop dragging
drag = false;
}
How do I drag and move an image around inside a Grid?
Have been trying to solve my problem for days, to no outcome.. here is my code for the xaml.
<Canvas>
<Grid Canvas.Left="134" Canvas.Top="98" Height="500" Width="1010">
<ContentControl x:Name="poolContainer">
</ContentControl>
<Grid DragEnter="Grid_DragEnter" AllowDrop="True">
<Image Canvas.Left="902" Canvas.Top="324" Height="42" Name="CueStick" Visibility="Visible" Source="/NYP_FYPJ_VP2014;component/Images/cue.png" Margin="780,230,-92,228" Drop="CueStick_DragDrop" MouseMove="CueStick_MouseMove" MouseDown="CueStick_MouseDown" MouseUp="CueStick_MouseUp"></Image>
</Grid>
</Grid>
<RepeatButton Canvas.Left="1175" Canvas.Top="397" Content="Rotate" Height="23" Name="buttonUp" Width="74" Click="buttonUp_Click" />
</Canvas>
Here is my xaml.cs code for the image drag
bool drag = false;
int x = 0;
int y = 0;
private bool isPictureReadyToDrag;
private void SetPosition()
{
CueStick.Location = new Point(MousePosition.X - this.Left - CueStick.Width / 2,
MousePosition.Y - this.Top - CueStick.Height);
}
private void CueStick_MouseMove(object sender, MouseEventArgs e)
{
if (isPictureReadyToDrag)
SetPosition();
}
private void CueStick_MouseDown(object sender, MouseButtonEventArgs e)
{
isPictureReadyToDrag = true;
SetPosition();
}
private void CueStick_MouseUp(object sender, MouseButtonEventArgs e)
{
isPictureReadyToDrag = false;
}
You are doing wrong in several places.
The image is put inside a Grid, its position is solely controlled by the Margin property, Canvas.Top/Left do not take effect and you can remove them.
<Image Canvas.Left="202" Canvas.Top="324" Margin="780,230,-92,228"
and in the code behind, set the image's Margin property, not Location (there is no such property).
CueStick.Margin = new Thickness(...
b. Set an explicit Width to the image, because you are using this value in the code behind.
<Image Width="229" Height="42"
c. You are not using the mouse position correctly; you can get it from MouseEventArgs/MouseButtonEventArgs, something like
private void CueStick_MouseDown(object sender, MouseButtonEventArgs e)
{
isPictureReadyToDrag = true;
double x = e.GetPosition(grid1).X;
double y = e.GetPosition(grid1).Y;
SetPosition(x, y);
}
private void SetPosition(double x, double y)
{
CueStick.Margin = new Thickness(x - CueStick.Width / 2,
y - CueStick.Height / 2, 0, 0);
}
Noted that grid1 is the containing Grid of the image.
<Grid x:Name="grid1" DragEnter="Grid_DragEnter" AllowDrop="True">
<Image...
The hard work of debugging to get the correct Margin is left to you.
I have checked this sample. It shows me TimeLineMarker API. Now when I press button "Add Marker" at that time markers are added and text block shows the markers, on which time it was added. Now I want to display those markers onto Slider control in the form of any sign like any shape or whatever, so when I want to go directly onto the marker I can go directly clicking on slider. How can I do this ?
Finally got answer from MSDN, thanks Matt
XAML
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<StackPanel VerticalAlignment="Center">
<Grid>
<Canvas x:Name="MyCanvas" Width="{Binding ElementName=MySlider, Path=ActualWidth}" Height="{Binding ElementName=MySlider, Path=ActualHeight}" Background="BlueViolet"/>
<Slider x:Name="MySlider" Orientation="Horizontal" Width="750" Height="50" Loaded="MySlider_Loaded_1"/>
</Grid>
<Button Content="Set marker" Click="Button_Click_1"/>
</StackPanel>
</Grid>
C#
int UniqueId = 0;
List<CustomTick> MyCustomTicks = new List<CustomTick>();
Thumb MySliderThumb;
Point ThumbCurrentPoint;
private void MySlider_Loaded_1(object sender, RoutedEventArgs e)
{
FrameworkElement templateRoot = VisualTreeHelper.GetChild((Slider)sender, 0) as FrameworkElement;
MySliderThumb = templateRoot.FindName("HorizontalThumb") as Thumb;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
MySliderThumb.TransformToVisual(MyCanvas).TryTransform(new Point(0, 0), out ThumbCurrentPoint);
CustomTick MyCustomTick = new CustomTick();
MyCustomTick.X = ThumbCurrentPoint.X;
MyCustomTick.Y = ThumbCurrentPoint.Y;
MyCustomTick.Value = MySlider.Value;
MyCustomTick.ID = UniqueId++;
MyCustomTicks.Add(MyCustomTick);
Windows.UI.Xaml.Shapes.Rectangle MyRectangle = new Windows.UI.Xaml.Shapes.Rectangle();
MyRectangle.Name = MyCustomTick.ID.ToString();
MyRectangle.Fill = new SolidColorBrush(Windows.UI.Colors.Red);
MyRectangle.Width = MySliderThumb.ActualWidth;
MyRectangle.Height = MySliderThumb.ActualHeight;
MyRectangle.PointerPressed += MyRectangle_PointerPressed;
MyCanvas.Children.Add(MyRectangle);
Canvas.SetTop(MyRectangle, MyCustomTick.Y - MyRectangle.Height );
Canvas.SetLeft(MyRectangle, MyCustomTick.X);
}
void MyRectangle_PointerPressed(object sender, PointerRoutedEventArgs e)
{
Windows.UI.Xaml.Shapes.Rectangle MyRectangle = sender as Windows.UI.Xaml.Shapes.Rectangle;
CustomTick MyCustomTick = new CustomTick();
foreach (CustomTick CT in MyCustomTicks)
{
if (CT.ID.ToString() == MyRectangle.Name)
{
MyCustomTick = CT;
break;
}
}
MySlider.Value = MyCustomTick.Value;
}
List<CustomTick> MyTicks = new System.Collections.Generic.List<CustomTick>();
private class CustomTick
{
public double X;
public double Y;
public double Value;
public int ID;
}
I am using the Thumb class to let the user drag and drop an image across a canvas. When the right button gets pressed, i want the user to be able to rotate the image. The rotation is based around the center of the image. I have the following XAML Code
<Grid>
<Canvas Background="Red" Grid.RowSpan="2" x:Name="canvas"
PreviewMouseRightButtonUp="Canvas_MouseUp"
PreviewMouseMove="Canvas_MouseMove">
<UserControl MouseRightButtonDown="Canvas_MouseDown" RenderTransformOrigin="0.5,0.5">
<Thumb Name="myRoot" DragDelta="myRoot_DragDelta">
<Thumb.Template>
<ControlTemplate>
<Grid>
<Image Source="/WpfApplication1;component/someImage.png" />
<Rectangle Stroke="#FF0061CE" StrokeThickness="1" Width="230" Height="250" />
</Grid>
</ControlTemplate>
</Thumb.Template>
</Thumb>
<UserControl.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="rotateTransform" />
<TranslateTransform x:Name="translateTransform" />
</TransformGroup>
</UserControl.RenderTransform>
</UserControl>
</Canvas>
</Grid>
And this code behind
bool isMouseDown = false;
Point pos;
double lastAngle = 0;
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
isMouseDown = true;
lastAngle = rotateTransform.Angle;
pos = Mouse.GetPosition(canvas);
}
private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
{
isMouseDown = false;
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (!isMouseDown) return;
var curPos = Mouse.GetPosition(canvas);
rotateTransform.Angle = lastAngle + (pos.Y - curPos.Y);
}
private void myRoot_DragDelta(object sender, DragDeltaEventArgs e)
{
translateTransform.X += e.HorizontalChange;
translateTransform.Y += e.VerticalChange;
}
It works if i only drag and drop the image around the screen and rotate the image a small amount (50 degrees in any direction seems ok). However manipulating it more than that and the image starts move around the screen unpredictibly.
I have tried moving the transformations to different controls, so to not to mix them up but have not received an acceptable result.
How can i get my code to behave like i want?
UPDATE: This is driving my crazy. I have changed the code and XAML to use a MatrixTransformation instead
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (!isMouseDown) return;
var curPos = Mouse.GetPosition(canvas);
angle = (lastAngle + (pos.Y - curPos.Y)) % 360;
UpdateMatrixTransform();
}
private void myRoot_DragDelta(object sender, DragDeltaEventArgs e)
{
posX += e.HorizontalChange;
posY += e.VerticalChange;
UpdateMatrixTransform();
}
void UpdateMatrixTransform()
{
Matrix m = new Matrix();
m.Rotate(angle);
m.OffsetX = posX;
m.OffsetY = posY;
matrixT.Matrix = m;
}
In my mind, this should work: First, rotate the graphic than move it to the offset. It does not work like i expect it to. It rotates the image, but than moves it strangely in spiral fashion outwards if i keep moving the mouse. No matter what i do, and in what order i execute my transformations, it wont work.
I'm not sure why you're using a UserControl to wrap the Thumb since it should be able to act as the root element here. Here is a solution that involes scrapping the use of TranslateTransform and instead using Canvas.Left and Canvas.Top properties:
EDIT: Updated Answer
Here's the XAML:
<Canvas x:Name="canvas">
<Thumb Name="myRoot"
Canvas.Left="0" Canvas.Top="0"
DragDelta="myRoot_DragDelta"
MouseMove="myRoot_MouseMove"
MouseDown="myRoot_MouseDown"
MouseUp="myRoot_MouseUp">
<Thumb.Template>
<ControlTemplate>
<Grid RenderTransformOrigin="0.5, 0.5">
<Rectangle Fill="AliceBlue"
Stroke="#FF0061CE"
StrokeThickness="1"
Width="100" Height="100"/>
<Grid.RenderTransform>
<RotateTransform x:Name="rotateTransform" />
</Grid.RenderTransform>
</Grid>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Canvas>
And here's the code behind:
public partial class TestWindow : Window
{
public TestWindow()
{
InitializeComponent();
}
Point? lastPosition = null;
RotateTransform rotateTransform;
private void myRoot_MouseDown(object sender, MouseButtonEventArgs e)
{
lastPosition = null;
if (e.ChangedButton == MouseButton.Right)
myRoot.CaptureMouse();
}
private void myRoot_MouseUp(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Right)
myRoot.ReleaseMouseCapture();
}
private void myRoot_MouseMove(object sender, MouseEventArgs e)
{
if (e.RightButton == MouseButtonState.Pressed)
{
Point curPosition = Mouse.GetPosition(myRoot);
if (lastPosition != null)
{
Point centerPoint = new Point(myRoot.ActualWidth / 2, myRoot.ActualWidth / 2);
if (rotateTransform == null)
rotateTransform = (RotateTransform)myRoot.Template.FindName("rotateTransform", myRoot);
rotateTransform.Angle = Math.Atan2(curPosition.Y - centerPoint.Y, curPosition.X - centerPoint.X) * 100;
}
lastPosition = curPosition;
e.Handled = true;
}
}
private void myRoot_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
Canvas.SetLeft(myRoot, Canvas.GetLeft(myRoot) + e.HorizontalChange);
Canvas.SetTop(myRoot, Canvas.GetTop(myRoot) + e.VerticalChange);
}
}
You have to tell the RotateTransform that you want to rotate around the center of the object rather than the center of the coordinate system, which is the default. To do that, set the CenterX and CenterY properties of the RotateTransform to the center of the object.