I am kind of lost what strategy to take. I need to do the following:
I have a toggle button as a base class. This button has all the properties as normal button, plus IsChecked, which tells us whether button is toggled or not.
I want to create a style (or a template) for ToggleButton. Basically it must inherit original style from ToggleButton, and add this:
IsChecked=True: Set ToolTip to "Collapse" and show this content (minus sign)
<Path Margin="2" Stroke="ForeGround property on control" Data="M0,5 H10" StrokeThickness="3" />
IsChecked=False, Set ToolTip tp "Expand" and show this content (plus sign)
<Path Margin="2" Stroke="ForeGround property on control" Data="M0,5 H10 M5,0 V10" StrokeThickness="3" />
I tried several approaches and always came up with some exception that I could not resolve.
Another approach can be to have one content only (plus sign), but divided to two lines:
<Grid>
<Path Margin="2" Stroke="ForeGround property on control" Data="M0,5 H10" StrokeThickness="3" />
<Path x:Name="verticalLine" Margin="2" Stroke="ForeGround property on control" Data="M5,0 V10" StrokeThickness="3" />
</Grid>
And them hange visibility of verticalLine based on expanded / collapsed state.
I made some progress:
<Style x:Key="myToggleButtonStyle" TargetType="ToggleButton" BasedOn="{StaticResource ToggleButtonStyle}">
<Setter Property="ContentTemplate">
<Setter.Value>
<Grid>
<Path Margin="2" Stroke="Black" Data="M0,5 H10" StrokeThickness="3" />
<Path x:Name="verticalLine" Margin="2" Stroke="Black" Data="M5,0 V10" StrokeThickness="3" />
</Grid>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.Target="verticalLine" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.Target="verticalLine" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
The only thing that I cannot do now is set Stroke to Foreground color of ToggleButton. I have tried all I rememberd, from TemplatedParent to AncestorType, and no success.
Try to change the Path.Data according to the ToggleButtons IsCheckedproperty:
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="ToolTip" Value="Collapsed"/>
<Setter Property="Content">
<Setter.Value>
<Path Margin="2" Stroke="{Binding Foreground, RelativeSource={RelativeSource AncestorType=ToggleButton}}" StrokeThickness="3">
<Path.Style>
<Style TargetType="Path">
<Setter Property="Data" Value="M0,5 H10 M5,0 V10 "/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton}, Path=IsChecked}" Value="True">
<Setter Property="Data" Value="M0,5 H10"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="ToolTip" Value="Expanded"/>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
Ok, here is the final solution:
<Style x:Key="MyToggleButtonStyle" TargetType="ToggleButton" BasedOn="{StaticResource ToggleButtonStyle}}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Path Margin="4" Data="M0,5 H10" Stretch="UniformToFill" Stroke="{TemplateBinding Control.Foreground}" StrokeThickness="3" />
<Path x:Name="verticalLine" Margin="4" Data="M5,0 V10" Stretch="UniformToFill" Stroke="{TemplateBinding Control.Foreground}" StrokeThickness="3" />
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="verticalLine" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="verticalLine" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
Related
<TabControl x:Name="tabControl" TabStripPlacement="Top" BorderBrush="White" FontSize="14" Grid.ColumnSpan="2" HorizontalAlignment="Left" Height="98" Margin="0,2,0,0" VerticalAlignment="Top" Width="992" FontFamily="Segoe UI">
<TabControl.Resources>
<Style TargetType="TabItem">
<Style.Triggers>
<Trigger Property="TabItem.IsSelected" Value="True">
<Setter Property="TabItem.Foreground" Value="#FF0090D3"/>
<Setter Property="TabItem.FontSize" Value="14"/>
<Setter Property="TabItem.FontFamily" Value="Segoe Ui SemiBold"/>
</Trigger>
</Style.Triggers>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Border Name="Border" BorderThickness="0,0,0,0" BorderBrush="White" Background="White" CornerRadius="13,13,13,13" Margin="1,0">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="10,2"/>
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<ParallelTimeline>
<ColorAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="(Border.Background).Color" From="White" To="LightGray" Duration="0:0:0.2"/>
</ParallelTimeline>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ParallelTimeline>
<ColorAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="(Border.Background).Color" From="LightGray" To="White" Duration="0:0:0.2"/>
</ParallelTimeline>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem Width="190" Visibility="Hidden" />
<TabItem Height="25" IsSelected="True" Width="63" Header="Home">
<Canvas>
<Rectangle x:name="rect1" Fill="#FFF4F4F5" Height="59" Width="58" Canvas.Top="3" Canvas.Left="1">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Fill.Color" To="LightGray" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Fill.Color" To="White" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</Canvas>
</TabItem>
<TabItem Width="63" Header="Tools"/>
<TabItem Width="76" Header="Add-ons" />
</TabControl>
The code allows me to change the tab header color when the mouse is over the header.However,the problem is....when mouse is over a content inside a tabitem,the MouseEnter event of both the TabItem and the content fires.Which results in : If i hover over a content(eg. a rectangle that i'm using),the MouseEnter event of the content/control is fired.But it also fires the 'MouseEnter' event of the tabItem...So the tabItem/TabHeader chages it's color even when i don't hover over the header/TabItem rather when i hover over a control/content inside the tabitem...How do i prevent this ?
Update
I found this code :
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true" />
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Top"/>
from here.But where should i put it ?
Damn!! It was reallllyyy easy! Just changed :
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
To :
<ControlTemplate.Triggers>
<EventTrigger SourceName="ContentSite" RoutedEvent="MouseEnter">
I have a validation template as below. But we can set the error icon either inside control or left of the control. Can you please tell me how can i make it blink at the right of the control (Outside the textBox and right)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Storyboard x:Key="FlashErrorIcon">
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Hidden}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:00.2000000" Value="{x:Static Visibility.Visible}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:00.4000000" Value="{x:Static Visibility.Hidden}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:00.6000000" Value="{x:Static Visibility.Visible}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:00.8000000" Value="{x:Static Visibility.Hidden}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:01" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Style x:Key="myErrorTemplate" TargetType="Control">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<Ellipse DockPanel.Dock="Left"
ToolTip="{Binding ElementName=myTextbox,
Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"
Width="15" Height="15"
Margin="-25,0,0,0"
StrokeThickness="1" Fill="Red" >
<Ellipse.Stroke>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="#FFFA0404" Offset="0"/>
<GradientStop Color="#FFC9C7C7" Offset="1"/>
</LinearGradientBrush>
</Ellipse.Stroke>
<Ellipse.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource FlashErrorIcon}"/>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
<TextBlock DockPanel.Dock="Left"
ToolTip="{Binding ElementName=myControl,
Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"
Foreground="White"
FontSize="11pt"
Margin="-15,5,0,0" FontWeight="Bold">!
<TextBlock.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource FlashErrorIcon}"/>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
<Border BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder Name="myControl"/>
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="TextBox" BasedOn="{StaticResource myErrorTemplate}" />
Change the location of the error icon via modifications to the template.
I've got the following datatemplate in a WPF app I'm working on. This provides an awesome swipe transition and was originally taken from this blog post.
What I'd like to do is get the same thing working in Silverlight 4. To my horror, SL4 is missing DataTriggers and certain storyboards. Can anyone shed light on the equivalents? Alternatively, can you point to a swipe transition on the web in Silverlight I can poach? Thanks!!
The Swipe Transition
<DataTemplate x:Key="SwipeTransition">
<DataTemplate.Resources>
<Visibility x:Key="Visible">Visible</Visibility>
<Storyboard x:Key="SlideStoryboard">
<DoubleAnimation
Storyboard.TargetName="container"
Storyboard.TargetProperty="RenderTransform.(TranslateTransform.X)"
From="0" FillBehavior="Stop"
Duration="0:0:0.3"
DecelerationRatio="1.0"/>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="a"
Storyboard.TargetProperty="Visibility"
Duration="0:0:0.3" FillBehavior="Stop">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource Visible}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="b"
Storyboard.TargetProperty="Visibility"
Duration="0:0:0.3" FillBehavior="Stop">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</DataTemplate.Resources>
<Grid ClipToBounds="True">
<Common:Transition x:Name="transition" Source="{Binding}" />
<Grid Name="container">
<Grid.RenderTransform>
<TranslateTransform X="{Binding ElementName=container, Path=ActualWidth, Converter={StaticResource NegativeConverter}}" />
</Grid.RenderTransform>
<ContentControl Name="a" Visibility="Hidden" Content="{Binding ElementName=transition, Path=DisplayA}" />
<ContentControl Name="b" Visibility="Hidden" Content="{Binding ElementName=transition, Path=DisplayB}" />
</Grid>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding ElementName=transition, Path=State}" Value="A">
<Setter TargetName="a" Property="Visibility" Value="Visible" />
<Setter TargetName="a" Property="RenderTransform">
<Setter.Value>
<TranslateTransform X="{Binding ElementName=container, Path=ActualWidth}" />
</Setter.Value>
</Setter>
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource SlideStoryboard}" />
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=transition, Path=State}" Value="B">
<Setter TargetName="b" Property="Visibility" Value="Visible" />
<Setter TargetName="b" Property="RenderTransform">
<Setter.Value>
<TranslateTransform X="{Binding ElementName=container, Path=ActualWidth}" />
</Setter.Value>
</Setter>
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource SlideStoryboard}" />
</DataTrigger.EnterActions>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
Which is applied as follows
<ContentControl x:Name="_exampleView" Content="{Binding SelectedExample.View}"
ContentTemplate="{StaticResource SwipeTransition}"/>
first a big thanks for the link.
May be you should look at this post How to create a WPF-like data trigger in Silverlight? they stated that VSM is the way to go for silverlight.
I want to write XAML code to change color of button when user changes selectionIndex of ListBox. How can I do it? I try
<Trigger Property="IsSelectionChanged" Value="True">
<Setter TargetName="btnSave" Property="Background" Value="Red" />
</Trigger>
But property IsSelectionChanged is not found.
There is no such property, you need to use an EventTrigger:
<Button Name="buton" Content="The Buton"/>
<ListBox ItemsSource="{Binding Data}">
<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
<Style.Triggers>
<EventTrigger RoutedEvent="SelectionChanged">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.Target="{x:Reference buton}"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Brushes.Red}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</ListBox.Style>
</ListBox>
I am applying a ItemContainerStyle to a ListBox control. In my ListBoxItem style I have several triggers containing storyboard animations that apply to the current state of the ListBoxItem (IsSelected, IsMouseOver).
It all works fine and dandy until after I have selected a ListBoxItem, then the IsMouseOver storyboard animation isn't fired for the ListBoxItem which was previously selected.
I can't see where the problem is, so I am hoping someone will help me out with this issue.
Cheers
Here is the code I am using
<Style x:Key="ListBoxFeedItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="2,0,0,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd" Background="{TemplateBinding Background}" Margin="5" SnapsToDevicePixels="true">
<Grid Name="Grid" Height="Auto" Margin="5">
<TextBlock Margin="10" Text="{Binding Path=Name}" FontSize="14" TextTrimming="CharacterEllipsis" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetName="Bd" Storyboard.TargetProperty="Background.Color" To="#4CDFDFDF" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetName="Bd" Storyboard.TargetProperty="Background.Color" To="#00DFDFDF" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetName="Bd" Storyboard.TargetProperty="Background.Color" To="#FFDFDFDF" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetName="Bd" Storyboard.TargetProperty="Background.Color" To="#00DFDFDF" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Check the order of your Triggers.
Have a look at Multiple storyboards on one property
Check out Yuri's answer.May be that's what you are looking for.