tags:

views:

21

answers:

1

Hi all,

I've video player with two button: Play and Pause. I want to use only one button. when user clicks on Play, the button appearance will changed to Pause and vice versa.

What is the better approach to achieve that task without using cs code behind?

I've tried to use DataTrigger to my IsPlaying property, but with no much success....

Here is my code:

<Window.Resources>
        <Viewbox x:Key="viewboxSource" >
            <Viewbox.Triggers>
                <DataTrigger Binding="{Binding IsPlaying}" Value="True">
                    <Setter Property="Path">
                        <Setter.Value>
                            <Path Stroke="Black" StrokeThickness="1" Fill="AliceBlue">
                                <Path.Data>
                                    <GeometryGroup>
                                        <EllipseGeometry Center="100,100" RadiusX="100" RadiusY="100"/>
                                    </GeometryGroup>
                                </Path.Data>
                            </Path>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Viewbox.Triggers>
        </Viewbox>
    </Window.Resources>
      <StackPanel>
        <Button Content="{StaticResource viewboxSource}"></Button>
     </StackPanel>

But I gut an error that says " 'Path' member is not valid because it does not have a qualifying type name " . Can anyone can help or give me a better solution?

+1  A: 

These kind of behaviour fits toggle button patern.

Make a style in your resources

       <Style x:Key="PlayToggleButtonStyle" TargetType="ToggleButton" >

and then define a templeate in it

            <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ToggleButton">

What is the most important here is to use VisualStateManager.

                       <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Disabled"/>
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="MouseOver"/>
                                <VisualState x:Name="Checked">
                                    <Storyboard>
                                        <DoubleAnimation Duration="0" To="2" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="border" />
                                        <ColorAnimation Duration="0:0:0.2" To="#FF392929" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="border"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Pressed">

                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

I use 2 animation. One moves button for 2 pixels and second change the gradient which gives a nice experience.

The only drawback is you need to use storyboards to handle these states. You need to add a Path object which I called Geometry nad mainupulate it.

            <Storyboard Storyboard.TargetName="Geometry" 
                        Storyboard.TargetProperty="Data">
              <ObjectAnimationUsingKeyFrames>
                <DiscreteObjectKeyFrame KeyTime="0" Value=""/> <!-- place the data here (how your button looks like) -->
              </ObjectAnimationUsingKeyFrames>
            </Storyboard>

But IMHO the better solution is to place 2 Path object in the template that on is over another and change the opacity of the top-most one.

    <Storyboard>
        <DoubleAnimation Storyboard.TargetName="TopGeometry" Storyboard.TargetProperty="Opacity" Duration="0:0:0.5" To="0.0">
            <DoubleAnimation.EasingFunction>
                <QuadraticEase EasingMode="EaseIn"/>
            </DoubleAnimation.EasingFunction>
        </DoubleAnimation>
    </Storyboard>

You would have a nice transition between these two states. What is more, no data is needed f.e IsPLaying property.

lukas