Hallo zusammen,
ich benötige Eure Hilfe und bedanke mich schonmal im Voraus.
Ich habe einen Style für einen ToggleButton. Dieser TB soll nach links und rechts sliden und dabei noch seine Farbe anpassen. Natürlich auch noch unter Beachtung seines Enabled-Status.
Gleichzeitig soll er die vorher aktive Farbe bei IsEnabled = True wieder erhalten. Der Style ansich funktioniert, aber leider nicht von Anfang an. Der TB ist, obwohl enabled und checked wie disabled und unchecked. Erst wenn man einmal drauf geklickt hat funktioniert er wie gefordert.
Gebunden ist der TB im View an ein ViewModel und die Werte werden auch korrekt abgeholt und gesetzt....
Ich habe auch hier im Forum gelesen, dass die Storyboards gestoppt werden sollten, das habe ich noch mit eingebaut.
Hat vielleicht jemand eine Idee, woran es liegen könnte?
<Style x:Key="AnimatedSwitchStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="#FAFAFB"/>
<Setter Property="BorderBrush" Value="#989898"/>
<Setter Property="IsEnabled" Value="True"/>
<Setter Property="IsChecked" Value="True"/>
<Setter Property="Margin" Value="5" />
<Setter Property="Height" Value="20" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<ControlTemplate.Resources>
<Storyboard x:Key="StoryboardBlue">
<ColorAnimation Storyboard.TargetProperty="Background.Color" To="#097de2" Duration="0:0:0.2" />
<ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="#097de2" Duration="0:0:0.2" />
</Storyboard>
<Storyboard x:Key="StoryboardGray">
<ColorAnimation Storyboard.TargetProperty="Background.Color" To="#989898" Duration="0:0:0.2" />
<ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="#989898" Duration="0:0:0.2" />
</Storyboard>
<Storyboard x:Key="StoryboardLightGray">
<ColorAnimation Storyboard.TargetProperty="Background.Color" To="#FAFAFB" Duration="0:0:0.2" />
<ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="#989898" Duration="0:0:0.2" />
</Storyboard>
<Storyboard x:Key="StoryboardRight">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(TranslateTransform.X)" Storyboard.TargetName="ellipse">
<SplineDoubleKeyFrame KeyTime="0" Value="0"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="15" KeySpline="0, 1, 0.6, 1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="StoryboardLeft">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(TranslateTransform.X)" Storyboard.TargetName="ellipse">
<SplineDoubleKeyFrame KeyTime="0" Value="15"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="0" KeySpline="0, 0.5, 0.5, 1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Viewbox Stretch="Uniform">
<Canvas Name="Layer_1"
Width="20"
Height="20"
Canvas.Left="10"
Canvas.Top="0">
<Ellipse Canvas.Left="0"
Width="20"
Height="20"
Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="0.5"/>
<Ellipse Canvas.Left="15"
Width="20"
Height="20"
Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="0.5"/>
<Border Canvas.Left="10"
Width="15"
Height="20"
Name="MyBorder" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,0.5,0,0.5"/>
<Ellipse x:Name="ellipse" Canvas.Left="0"
Width="20"
Height="20"
Fill="White" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="0.3">
<Ellipse.RenderTransform>
<TranslateTransform X="0" Y="0" />
</Ellipse.RenderTransform>
<Ellipse.BitmapEffect>
<DropShadowBitmapEffect Softness="0.1" ShadowDepth="0.7" Direction="270" Color="#BBBBBB"/>
</Ellipse.BitmapEffect>
</Ellipse>
<Label x:Name="Test" Content="Hallo" Width="500"/>
</Canvas>
</Viewbox>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsEnabled" Value="False">
<Trigger.EnterActions>
<BeginStoryboard x:Name="BeginStoryboardLightGray" Storyboard="{StaticResource StoryboardLightGray}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="BeginStoryboardLightGray"/>
</Trigger.ExitActions>
<Setter TargetName="Test" Property="Content" Value="IsEnabled"></Setter>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Trigger.EnterActions>
<BeginStoryboard x:Name="BeginStoryboardRight" Storyboard="{StaticResource StoryboardRight}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="BeginStoryboardRight"/>
</Trigger.ExitActions>
<Setter TargetName="Test" Property="Content" Value="IsChecked"></Setter>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="False">
<Trigger.EnterActions>
<BeginStoryboard x:Name="BeginStoryboardLeft" Storyboard="{StaticResource StoryboardLeft}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="BeginStoryboardLeft"/>
</Trigger.ExitActions>
<Setter TargetName="Test" Property="Content" Value="IsNotChecked"></Setter>
</Trigger>
<MultiTrigger >
<MultiTrigger.Conditions>
<Condition Property="ToggleButton.IsChecked" Value="True"/>
<Condition Property="ToggleButton.IsEnabled" Value="True"/>
</MultiTrigger.Conditions>
<MultiTrigger.EnterActions>
<BeginStoryboard x:Name="BeginStoryboardBlue2" Storyboard="{StaticResource StoryboardBlue}"/>
</MultiTrigger.EnterActions>
<MultiTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="BeginStoryboardBlue2"/>
</MultiTrigger.ExitActions>
<Setter TargetName="Test" Property="Content" Value="IsEnabled und IsChecked"></Setter>
</MultiTrigger>
<MultiTrigger >
<MultiTrigger.Conditions>
<Condition Property="ToggleButton.IsChecked" Value="False"/>
<Condition Property="ToggleButton.IsEnabled" Value="True"/>
</MultiTrigger.Conditions>
<MultiTrigger.EnterActions>
<BeginStoryboard x:Name="BeginStoryboardGray2" Storyboard="{StaticResource StoryboardGray}"/>
</MultiTrigger.EnterActions>
<MultiTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="BeginStoryboardGray2"/>
</MultiTrigger.ExitActions>
<Setter TargetName="Test" Property="Content" Value="IsEnabled und IsNotChecked"></Setter>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Ich habe gerade mal den Style in Blend überprüft. Dort verhält der sich wunderbar....sehr seltsam.
Hallo Mexxchen,
ich habe deinen Style in VS 2010 eingebunden und es hat auch funktioniert.
Beim Starten der Anwendung: blaue Farbe im ersten Kreis (zweiter Teil weiß, blau umrandet) mit der Beschriftung ISEnabled und IsChecked beim Anzeigen Buttons im Window. Klickt man drauf wird der blaue Kreis weiß (grau umrandet) und der zweite Kreis grau (Beschriftung IsEnabled und IsNotChecked), Slide funktioniert also auch. Klickt man wieder drauf ist der Anfangzustand wieder vorhanden, also blaue Färbung etc. Sollte also wie gewünscht funktionieren, oder?
Es scheint, als wäre der Style wirklich in Ordnung.
Style wurde wie folgt genutzt:
<ToggleButton Style="{StaticResource AnimatedSwitchStyle}" />
Den Style selbst habe ich in <Application.Resources> im Bereich <ResourceDictionary> der App.xaml eingefügt.
Gruß Sarah
Hey Sarah, danke für die Bestätigung.
ich hab nun einiges probiert und bin zu folgendem Style gekommen, welcher meine gewollte Funktion erfüllt. Es kam dabei auch noch auf die Reihenfolge der Trigger an.
<Style x:Key="AnimatedSwitchStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="#FAFAFB"/>
<Setter Property="BorderBrush" Value="#989898"/>
<Setter Property="IsEnabled" Value="True"/>
<Setter Property="IsChecked" Value="True"/>
<Setter Property="Margin" Value="5" />
<Setter Property="Height" Value="20" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Viewbox Stretch="Uniform">
<Canvas Name="Layer_1"
Width="20"
Height="20"
Canvas.Left="10"
Canvas.Top="0">
<Ellipse Canvas.Left="0"
Width="20"
Height="20"
Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="0.5"/>
<Ellipse Canvas.Left="15"
Width="20"
Height="20"
Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="0.5"/>
<Border Canvas.Left="10"
Width="15"
Height="20"
Name="MyBorder" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,0.5,0,0.5"/>
<Ellipse x:Name="ellipse" Canvas.Left="0"
Width="20"
Height="20"
Fill="White" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="0.3">
<Ellipse.RenderTransform>
<TranslateTransform X="0" Y="0" />
</Ellipse.RenderTransform>
<Ellipse.BitmapEffect>
<DropShadowBitmapEffect Softness="0.1" ShadowDepth="0.7" Direction="270" Color="#BBBBBB"/>
</Ellipse.BitmapEffect>
</Ellipse>
</Canvas>
</Viewbox>
<ControlTemplate.Triggers>
<!-- Verändern des Sliders und der Farbe sofern checked = true oder false -->
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<!-- signalisieren, dass ToggleButton checked = true ist -->
<ColorAnimation Storyboard.TargetProperty="Background.Color" To="#097de2" Duration="0:0:0.2" />
<ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="#097de2" Duration="0:0:0.2" />
<!-- Slider nach rechts schieben -->
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(TranslateTransform.X)" Storyboard.TargetName="ellipse">
<SplineDoubleKeyFrame KeyTime="0" Value="0"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="15" KeySpline="0, 1, 0.6, 1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<!-- signalisieren, dass ToggleButton checked = false ist -->
<ColorAnimation Storyboard.TargetProperty="Background.Color" To="#989898" Duration="0:0:0.2" />
<ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="#989898" Duration="0:0:0.2" />
<!-- Slider nach links schieben -->
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(TranslateTransform.X)" Storyboard.TargetName="ellipse">
<SplineDoubleKeyFrame KeyTime="0" Value="15"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="0" KeySpline="0, 0.5, 0.5, 1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<!-- ToggleButton ist aktiviert oder deaktiviert -->
<Trigger Property="ToggleButton.IsEnabled" Value="False">
<Trigger.EnterActions>
<BeginStoryboard x:Name="StoryboardLightGray">
<Storyboard>
<!-- signalisieren, dass ToggleButton nicht checkbar ist -->
<ColorAnimation Storyboard.TargetProperty="Background.Color" To="#FAFAFB" Duration="0:0:0.2" />
<ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="#989898" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="StoryboardLightGray"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Ich habe noch eine kleine Frage zu den Animationen. Ist es möglich, dass man die Bewegung auf der X-Achse dynamisch anpasst, wenn man die ViewBox weglassen will? Wenn ich den X-Value an z.B. die Width der Ellipse o. ä. binde (zum Test), kommt ein Fehler "Diese Storyboard-Zeitleistenstruktur kann nicht für die threadübergreifende Verwendung fixiert werden."
Die Bewgung auf der X-Achse soll quasi 'mitwachsen' wenn die Größenverhältnisse angepasst werden.
Edit: Laut diesem Link WPF animation: binding to the “To” attribute of storyboard animation scheint es nicht möglich zu sein. da muss man wohl mit einer ViewBox vorlieb nehmen, oder?