0

I have this code that display a rectangle on a canvas :

XAML :

<Window x:Class="rotateRect.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:rotateRect"
    mc:Ignorable="d"
    Title="MainWindow" Height="402.027" Width="600.676">
<Grid>

    <Canvas Name="my_c" HorizontalAlignment="Left" Height="24" Margin="160,149,0,0"  VerticalAlignment="Top" Width="177" RenderTransformOrigin="0.5,0.5">
        <Canvas.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform Angle="-68.962"/>
                <TranslateTransform/>
            </TransformGroup>
        </Canvas.RenderTransform>
    </Canvas>

</Grid>

I can turn it in XAML with "RenderTransform". But i wanted to implement this rotation in c# and create a "propeller". I tried to find information about "RotateTransform" for a canvas. Thys is my c# code :

C# :

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace rotateRect
{
    public partial class MainWindow : Window
    {
        Rectangle my_r = new Rectangle();

        public MainWindow()
        {
            InitializeComponent();
            initializeRect(my_r, my_c);
        }

        private void initializeRect(Rectangle r, Canvas c)
        {
            // rectangle 
            r.Width = 10;
            r.Height = 50;

            // rectangle Color
            r.Fill = new SolidColorBrush(Color.FromRgb(0, 0, 255));

            // canvas 
            c.Children.Add(r);
            c.Width = 10;
            c.Height = 50;
        }
    }
}

I found an exemple of "RotateTransform" for a bitmap object but i hadn't find anything for a canvas. C#, rotating Graphics?

It's possible to apply a RotateTransform to a canvas in c#?

Community
  • 1
  • 1
Jguillot
  • 214
  • 3
  • 14

2 Answers2

0

modify your initializeRect methode

private void initializeRect(Rectangle r, Canvas c)
        {
            // rectangle 
            r.Width = 10;
            r.Height = 50;

            // rectangle Color
            r.Fill = new SolidColorBrush(Color.FromRgb(0, 0, 255));

            // canvas 
            c.Children.Add(r);
            c.Width = 10;
            c.Height = 50;

            RotateTransform rt = new RotateTransform();
            rt.Angle=-68.962;
            c.RenderTransform = rt;
        }
vijay.k
  • 179
  • 1
  • 10
0

By 'propeller' you mean animation? For that you'll need, well, animation. Only RotateTransform is not enough.

For example, let's copy your Canvas with Rectangle but in XAML:

<Canvas Name="cnvs" VerticalAlignment="Center" HorizontalAlignment="Center"
        Loaded="cnvs_Loaded">
    <Canvas.Resources>
        <DoubleAnimation x:Key="rotator" From="0" To="360" Duration="0:0:1"
                         AutoReverse="False" RepeatBehavior="Forever" />
    </Canvas.Resources>
    <Canvas.RenderTransform>
        <RotateTransform x:Name="canvasRotation" />
    </Canvas.RenderTransform>

    <Rectangle Width="10" Height="50" Fill="Blue" />
</Canvas>

And start the animation in our Loaded event handler. Canvas has it's own sizing quirks so we need to set CenterX and CenterY poperties for our transform:

private void cnvs_Loaded(object sender, RoutedEventArgs e)
{
     var canvas = (Canvas) sender;
     var animation = canvas.Resources["rotator"] as DoubleAnimation;

     var children = canvas.Children.OfType<FrameworkElement>().ToArray();
     canvasRotation.CenterX = children.Max(c => c.ActualWidth) / 2;
     canvasRotation.CenterY = children.Max(c => c.ActualHeight) / 2;

     canvasRotation.BeginAnimation(RotateTransform.AngleProperty, animation);
 }


But do you really need a Canvas here? We can simplify things with Grid, for example:
<Grid Name="grid" VerticalAlignment="Top" HorizontalAlignment="Left"
        Loaded="grid_Loaded" RenderTransformOrigin="0.5,0.5">
    <Grid.Resources>
        <DoubleAnimation x:Key="rotator" From="0" To="360" Duration="0:0:1"
                         AutoReverse="False" RepeatBehavior="Forever" />
    </Grid.Resources>
    <Grid.RenderTransform>
        <RotateTransform x:Name="gridRotation" />
    </Grid.RenderTransform>

    <Rectangle Width="10" Height="50" Fill="Blue" />
</Grid>

And

private void grid_Loaded(object sender, RoutedEventArgs e)
{
     var g = (Grid) sender;
     var animation = g.Resources["rotator"] as DoubleAnimation;        
     gridRotation.BeginAnimation(RotateTransform.AngleProperty, animation);
}

Or animate just the Recntagle if it's the only object you'll have in the container. No need to complicate things.

icebat
  • 4,696
  • 4
  • 22
  • 36
  • Hi, thanks for your answer. To simulate a "propeller", i created a "Timer" like this : http://www.wpf-tutorial.com/misc/dispatchertimer/ It launch my function "propeller" each tick. This simulate a rectangle wich turn like a propeller. I didn't add to my code because i didn't want to surcharge it. I can edit my code above to show you how i implemented it. – Jguillot Mar 02 '16 at 12:21
  • @Jguillot, no need, creating controls in code behind and animating them with timers is too WinForms-ey, and not really a WPF approach. But you're free to implement it any way you like, of course. – icebat Mar 02 '16 at 12:24