WPF rotating button

12,837

Solution 1

Have a look at Viewport2DVisual3D

The example in the link does exactly that.

Edit: Here is the example from the link with an added animation of the Z axis

Looks like this
enter image description here

<Viewport3D>
    <Viewport3D.Camera>
        <PerspectiveCamera Position="0, 0, 4"/>
    </Viewport3D.Camera>
    <Viewport2DVisual3D x:Name="v2dv3d">
        <Viewport2DVisual3D.Transform>
            <RotateTransform3D>
                <RotateTransform3D.Rotation>
                    <AxisAngleRotation3D Angle="0" Axis="0, 1, 0" />
                </RotateTransform3D.Rotation>
            </RotateTransform3D>
        </Viewport2DVisual3D.Transform>
        <Viewport2DVisual3D.Geometry>
            <MeshGeometry3D Positions="-1,1,0 -1,-1,0 1,-1,0 1,1,0"
                    TextureCoordinates="0,0 0,1 1,1 1,0" TriangleIndices="0 1 2 0 2 3"/>
        </Viewport2DVisual3D.Geometry>

        <Viewport2DVisual3D.Material>
            <DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True" Brush="White"/>
        </Viewport2DVisual3D.Material>
        <Button Content="Hello, 3D">
            <Button.Triggers>
                <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                    <BeginStoryboard>
                        <Storyboard RepeatBehavior="Forever">
                            <Rotation3DAnimation Storyboard.TargetName="v2dv3d"
                                                    Storyboard.TargetProperty="(Viewport2DVisual3D.Transform).(RotateTransform3D.Rotation)"
                                                    Duration="0:0:2"
                                                    BeginTime="0:0:0">
                                <Rotation3DAnimation.From>
                                    <AxisAngleRotation3D Angle="0" Axis="0, 1, 0" />
                                </Rotation3DAnimation.From>
                                <Rotation3DAnimation.To>
                                    <AxisAngleRotation3D Angle="90" Axis="0, 1, 0" />
                                </Rotation3DAnimation.To>
                            </Rotation3DAnimation>
                            <Rotation3DAnimation Storyboard.TargetName="v2dv3d"
                                                    Storyboard.TargetProperty="(Viewport2DVisual3D.Transform).(RotateTransform3D.Rotation)"
                                                    Duration="0:0:2"
                                                    BeginTime="0:0:2">
                                <Rotation3DAnimation.From>
                                    <AxisAngleRotation3D Angle="-90" Axis="0, 1, 0" />
                                </Rotation3DAnimation.From>
                                <Rotation3DAnimation.To>
                                    <AxisAngleRotation3D Angle="0" Axis="0, 1, 0" />
                                </Rotation3DAnimation.To>
                            </Rotation3DAnimation>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Button.Triggers>
        </Button>
    </Viewport2DVisual3D>
    <ModelVisual3D>
        <ModelVisual3D.Content>
            <DirectionalLight Color="#FFFFFFFF" Direction="0,0,-1"/>
        </ModelVisual3D.Content>
    </ModelVisual3D>
</Viewport3D>

Solution 2

Transformations may help you in this case. Look at here if that helps.

The RotateTransform class is used to rotate a WPF object in an X-Y plane. It can be applied via XAML or directly via imperative code.

Solution 3

If you only need to rotate your button about the Z axis, then you won't need any 3D graphics. All UIElements (such as Buttons) have the property RenderTransform, which enables basic transformation of their default appearance. By means of Storyboards, WPF allows you to animate almost any dependency property. You can use a storyboard, triggered on load, to animate the Angle property of a RotateTransform applied to the button:

<Button Width="100" Height="100" Content="Wheeee!">
  <Button.Triggers>
    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
      <BeginStoryboard>
        <Storyboard Storyboard.TargetName="ButtonRotation" Storyboard.TargetProperty="Angle">
          <DoubleAnimation From="0" To="360" Duration="0:0:3" RepeatBehavior="Forever"/>
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
  <Button.RenderTransform>
    <RotateTransform x:Name="ButtonRotation" CenterX="50" CenterY="50" Angle="45"/>
  </Button.RenderTransform>
</Button>

The Viewport2DVisual3D, as recommended by @Meleak, also supports animation, and is fun to play with if you have time. To animate the MSDN example, you need to add a name to the AxisAngleRotation3D element and switch it to target the Z axis:

<AxisAngleRotation3D x:Name="RotateAboutZ" Angle="40" Axis="0, 0, 1" />

Then, as above, trigger a storyboard to begin on the Loaded event of the Viewport3D. In either case, if you need more control over the animation, you can make your storyboard a named resource to be referenced by other events, or even build and control it entirely in code.

Share:
12,837
Yevgeniy
Author by

Yevgeniy

Updated on June 07, 2022

Comments

  • Yevgeniy
    Yevgeniy almost 2 years

    Help me plz. I need to animate rotation of the button on z-axis without using external libraries, only with C# and xaml code.

    Is that possible? How can I do that?

    Thanks.

  • Yevgeniy
    Yevgeniy over 12 years
    Thank you for your answer. I was not precise. I need to animate this process.
  • Fredrik Hedblad
    Fredrik Hedblad over 12 years
    @Eugene: Updated my answer with a z axis animation. Paste it and try it :)
  • Kimberly
    Kimberly over 12 years
    @Meleak This is a Y-axis rotation. If you change the axis to Z, you can also simplify the storyboard, because the button will never turn away from the camera.
  • Fredrik Hedblad
    Fredrik Hedblad over 12 years
    @Kimberly: True, this isn't Z-axis (mixed up 3d with Z-axis) but I have a feeling this effect was what the OP wanted. Like a rotating logotype in 3D (I could be wrong of course)
  • Ladessa
    Ladessa about 11 years
    @Meleak pls, see my question stackoverflow.com/questions/15499764/… I need rotate my panel when user click on the button...