2017-12-13 143 views
12

Mam pole wyboru zastępujące kontrolkę podobną do przełącznika.Zatrzymywanie/blokowanie animacji dla kontrolki pola wyboru

enter image description here

enter image description here

Działa świetnie. Jedynym problemem jest to, że ten początkowy tryb pola wyboru może być prawdziwy lub fałszywy. Dla fałszu - nie ma problemu, ale jeśli to prawda, to po załadowaniu widoku od razu widać animację przełącznika w ruchu.

Chcę temu zapobiec. Czy tak jest?

Oto odnośny 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> 

ten sposób zainicjować pogląd + ViewModel:

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

// ctor of viewmodel 
public MonitoredExtensionsViewModel() 
{ 
    ... 
    ExplicitIncludeMode = true/false; 
    ... 
} 
+0

Nie całkiem odtwarzam problem. Jeśli skopiuję wklej swój kod w nowym WpfApp, to zawsze pokazuje to samo i nie reaguje tak, jak powinien (jeśli rozumiem poprawnie), używając false lub true. –

+0

@SimonMourier hmmm jak ustawić początkowy stan pola wyboru? Czy robisz to przed wywołaniem InitializeComponent dla widoku? –

+0

Po prostu próbowałem ustawić IsChecked = true i false –

Odpowiedz

4

Znaleziono 1 sposób to zrobić.

Okazuje się, że można związać początkowe położenie X przełącznika/suwaka. Więc przywiązałem go do właściwości w ViewModel i zaktualizowałem.

Zmiany w XAML:

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

konstruktor widzenia:

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

konstruktor z ViewModel:

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

więcej od ViewModel:

public Double InitialPosition { get; set; } 

Po załadowaniu widoku tworzony jest viewmodel, a pierwotna/początkowa lokalizacja suwaka jest obliczana zgodnie ze stanem pola wyboru.