1

I have a WPF aplication and here I want to override the ugly default WPF styles. I have created the Styles.xaml dictionary and here I have almost finished with styles, but there are some problems with animation and smooth transition between different visual states (triggers).

One of my challenges was that I don't want to have any C# event handlers or other C# code bound to styles.

Here I provide some code on my trigger:

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="IsEnabled" Value="True" />
        <Condition Property="IsMouseOver" Value="True" />
        <Condition Property="IsPressed" Value="False" />
    </MultiTrigger.Conditions>
    <MultiTrigger.EnterActions>
        <BeginStoryboard Name="MouseOverStoryboard">
            <Storyboard Duration="0:0:0.25" SlipBehavior="Grow">
                <ColorAnimation Storyboard.TargetName="InnerBorder" 
                                Storyboard.TargetProperty="Background.(SolidColorBrush.Color)" 
                                To="{StaticResource White}" 
                                BeginTime="0:0:0" Duration="0:0:0.25" />
                <DoubleAnimation Storyboard.TargetName="InnerBorder" 
                                 Storyboard.TargetProperty="Opacity" 
                                 To="0.3" 
                                 BeginTime="0:0:0" Duration="0:0:0.25" />
            </Storyboard>
        </BeginStoryboard>
    </MultiTrigger.EnterActions>
    <MultiTrigger.ExitActions>
        <RemoveStoryboard BeginStoryboardName="MouseOverStoryboard" />
    </MultiTrigger.ExitActions>
</MultiTrigger>

To make animation smooth I added EnterAction and put Storyboard here with timings, so entering animation is smooth and looking well.

My first question was about how to get back to default color when my BeginStoryboard was executed, but then I realised I can use RemoveStoryboard.

Now I really don't know I my ideas are out - how to make smooth exit animation? Shouldn't I use RemoveStoryboard?

Please provide suggestions. Thanks.

P. S. I'm not using VisualStateManager, because of lack of states and I don't want to implement my own controls for that.

Tomas
  • 1,212
  • 1
  • 9
  • 10

1 Answers1

1

How about adding a new animation object that starts when the enter action animation duration elapsed. Or how about using the ExitAction property of your Trigger by adding a Storyboard that reverts your EnterAction. Or you could try to set the Fillbehavior property to 'Stop...

Another option is to use an EventSetter to catch RoutedEvents like MouseEnter and MouseLeave.

BionicCode
  • 1
  • 4
  • 28
  • 44
  • Then the first behavior is bad. I have the MouseOver event, if I set the FillBehavior to Stop, then after the animation my button becomes like default style. It must be MouseOver style. – Tomas Sep 02 '15 at 06:24
  • Then why don't add another BeginStoryboard to your ExitActions? You could also add another Trigger that triggers when IsMousOver == false. Or setting the Background property can be also achieved by using a simple Setter in your Trigger. This will automatically revert settings if the Trigger becomes invalid. – BionicCode Sep 02 '15 at 06:30
  • Because the default-state color can be not the one I set from style. If user puts his color brush from his View, then another BeginStoryboard will override that color and get back to the one that I predefine... – Tomas Sep 02 '15 at 06:32
  • Use an EventSetter (MouseEnter, MouseLeave) – BionicCode Sep 02 '15 at 06:39
  • I don't think controlling your controls visual state concurrently from many places by different objects is a good way to do so. You should define the controls behavior (or VisualState) in only one place, e.g. like in the template. – BionicCode Sep 02 '15 at 06:45
  • 1
    I think it's more clean to use a static resource brush like "DefaultBackgroundBrush". Your application will only change the color of that Brush to set a new default color. Now in your triggers, that control the visual state, you can set it back explicitly to "Background={StaticResource DefaultBackgroundBrush}" or as i wrote before just use a common Setter. The value will return to previous state as soon as the trigger becomes invalid. Using this approach you don't need to care about the actual default color. It's whatever the current Color of DefaultBackgroundBrush is like. – BionicCode Sep 02 '15 at 07:09