Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pause/prevent animation for a checkbox control

Tags:

c#

mvvm

wpf

I have a checkbox substituting a switch-like control.

enter image description here

enter image description here

It works great. The only problem is that this checkbox initial mode can be either true or false. For false - no problem, but if it's true, then when the view is loaded, you immediately see the animation of the switch moving.

I want to prevent that. Is there anyway to do so?

Here's the relevant XAML:

<CheckBox Style="{StaticResource MySwitch}"  IsChecked="{Binding ExplicitIncludeMode}" ></CheckBox>

<Style x:Key="MySwitch" TargetType="{x:Type CheckBox}">
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
                <ControlTemplate.Resources>
                    <Storyboard x:Key="OnChecking">
                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
                            <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="55"/>
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                    <Storyboard x:Key="OnUnchecking">
                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
                            <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
                        </DoubleAnimationUsingKeyFrames>
                        <ThicknessAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(FrameworkElement.Margin)">
                            <SplineThicknessKeyFrame KeyTime="00:00:00.3000000" Value="1,1,1,1"/>
                        </ThicknessAnimationUsingKeyFrames>
                    </Storyboard>
                </ControlTemplate.Resources>

                <DockPanel x:Name="dockPanel">
                    <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" ContentTemplate="{TemplateBinding ContentTemplate}" RecognizesAccessKey="True" VerticalAlignment="Center"/>
                    <Border BorderBrush="LightGray" BorderThickness="1" Margin="5,5,0,5">
                        <Grid  Width="110" Background="GhostWhite">
                            <TextBlock Text="Included" TextWrapping="Wrap" FontWeight="Medium" FontSize="12" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,3,0" Foreground="#FF00AFC4"/>
                            <TextBlock HorizontalAlignment="Left" Margin="2,0,0,0" FontSize="12" FontWeight="Bold" Text="Excluded" VerticalAlignment="Center" TextWrapping="Wrap" Foreground="#FFE4424D"/>
                            <Border HorizontalAlignment="Left" x:Name="slider" Width="55" BorderThickness="1,1,1,1" CornerRadius="3,3,3,3" RenderTransformOrigin="0.5,0.5" Margin="1,1,1,1">
                                <Border.RenderTransform>
                                    <TransformGroup>
                                        <ScaleTransform ScaleX="1" ScaleY="1"/>
                                        <SkewTransform AngleX="0" AngleY="0"/>
                                        <RotateTransform Angle="0"/>
                                        <TranslateTransform X="0" Y="0"/>
                                    </TransformGroup>
                                </Border.RenderTransform>
                                <Border.BorderBrush>
                                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                        <GradientStop Color="WhiteSmoke" Offset="0"/>
                                        <GradientStop Color="#FFFFFFFF" Offset="1"/>
                                    </LinearGradientBrush>
                                </Border.BorderBrush>
                                <Border.Background>
                                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                        <GradientStop x:Name="grdColor" Color="#FF00AFC4" Offset="1"/>
                                        <GradientStop Color="#092E3E" Offset="0"/>
                                    </LinearGradientBrush>
                                </Border.Background>
                            </Border>
                        </Grid>
                    </Border>
                </DockPanel>

                <ControlTemplate.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsChecked" Value="True"/>
                            <Condition Property="IsPressed" Value="True"/>
                        </MultiTrigger.Conditions>

                        <MultiTrigger.ExitActions>
                            <BeginStoryboard Storyboard="{StaticResource OnUnchecking}" x:Name="OnUnchecking_BeginStoryboard"/>
                        </MultiTrigger.ExitActions>
                        <MultiTrigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource OnChecking}" x:Name="OnChecking_BeginStoryboard"/>
                        </MultiTrigger.EnterActions>
                    </MultiTrigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Width" Value="118"></Setter>
    <Setter Property="Height" Value="39"></Setter>

</Style>

This is the way I initialize the view + viewmodel:

// ctor of view (tab)
public MonitoredExtensions()
{
    InitializeComponent();
    DataContext = new MonitoredExtensionsViewModel();
}

// ctor of viewmodel
public MonitoredExtensionsViewModel()
{
     ...
     ExplicitIncludeMode = true/false;
     ...
}
like image 390
Maverick Meerkat Avatar asked Dec 13 '17 15:12

Maverick Meerkat


1 Answers

Found 1 way to do this.

Turns out you can bind the initial X location of the switch/slider. So I binded it to a property in the ViewModel, and updated it.

Changes to XAML:

<TranslateTransform X="{Binding InitialPosition}" Y="0"/>

Ctor of View:

public MonitoredExtensions()
{
    InitializeComponent();
    DataContext = new MonitoredExtensionsViewModel();
}

Ctor of ViewModel:

public MonitoredExtensionsViewModel()
{
     ...
     ExplicitIncludeMode = true/false;
     InitialPosition = (ExplicitIncludeMode) ? 55 : 0;
     ...
}

More from the ViewModel:

public Double InitialPosition { get; set; }

So as the view is loaded, the viewmodel is being created, and the original/initial location of the slider is calculated according to the checkbox state.

like image 177
Maverick Meerkat Avatar answered Oct 01 '22 03:10

Maverick Meerkat