Separate CustomControl's visual state manager from its style - c#

I am following along this awesome tutorial about custom controls, and in the fourth video of the playlist, Sean goes over visual states. In his AnalogClockStyle.xaml, he demonstrates a simple visual state manager inside the control's grid, but I can imagine this is not viable for more intricately designed custom controls if you just want to analyse their control templates.
Is there a way to separate out the visual state manager from the control template's style file? I would ideally like to create folders for Custom Control *.cs files, their control template *.xaml files, their respective style *.xaml files and finally their visual state manager files (if possible).
Here's what the current control template looks like:
<Style TargetType="local:AnalogClock">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:AnalogClock">
<ControlTemplate.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<converters:GreaterThanMultiConverter x:Key="GreaterThanMultiConverter"/>
<converters:DivisionConverter x:Key="DivisionConverter"/>
</ControlTemplate.Resources>
<Grid x:Name="Clock" RenderTransformOrigin="0.5 0.5">
<Grid.RenderTransform>
<RotateTransform Angle="90"/>
</Grid.RenderTransform>
<!-- Move the Visual State Manager code to a separate file? -->
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="TimeStates">
<VisualState x:Name="Day">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ClockFill"
Storyboard.TargetProperty="Color"
To="SkyBlue"/>
<ColorAnimation Storyboard.TargetName="HourStroke"
Storyboard.TargetProperty="Color"
To="Gold"/>
<ColorAnimation Storyboard.TargetName="MinuteStroke"
Storyboard.TargetProperty="Color"
To="Gold"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Night">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ClockFill"
Storyboard.TargetProperty="Color"
To="Black"/>
<ColorAnimation Storyboard.TargetName="HourStroke"
Storyboard.TargetProperty="Color"
To="White"/>
<ColorAnimation Storyboard.TargetName="MinuteStroke"
Storyboard.TargetProperty="Color"
To="White"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Christmas">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ClockFill"
Storyboard.TargetProperty="Color"
To="Green"/>
<ColorAnimation Storyboard.TargetName="HourStroke"
Storyboard.TargetProperty="Color"
To="Red"/>
<ColorAnimation Storyboard.TargetName="MinuteStroke"
Storyboard.TargetProperty="Color"
To="Red"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!-- Move the Visual State Manager code to a separate file? -->
<Ellipse x:Name="PART_Clock" Stroke="Black" StrokeThickness="1">
<Ellipse.Style>
<Style TargetType="Ellipse">
<Setter Property="Width" Value="{Binding ActualHeight, ElementName=Clock}"/>
<Setter Property="Height" Value="auto"/>
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource GreaterThanMultiConverter}">
<MultiBinding.Bindings>
<Binding Path="ActualHeight" ElementName="Clock"/>
<Binding Path="ActualWidth" ElementName="Clock"/>
</MultiBinding.Bindings>
</MultiBinding>
</DataTrigger.Binding>
<DataTrigger.Setters>
<Setter Property="Height" Value="{Binding ActualWidth, ElementName=Clock}"/>
<Setter Property="Width" Value="auto"/>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
<Ellipse.Fill>
<SolidColorBrush x:Name="ClockFill" Color="White"/>
</Ellipse.Fill>
</Ellipse>
<Line x:Name="PART_HourHand" StrokeThickness="1" VerticalAlignment="Center" HorizontalAlignment="Center" X1="0"
X2="{Binding ActualHeight, ElementName=PART_Clock, Converter={StaticResource DivisionConverter}, ConverterParameter=-4}">
<Line.Stroke>
<SolidColorBrush x:Name="HourStroke" Color="Black"/>
</Line.Stroke>
</Line>
<Line x:Name="PART_MinuteHand" StrokeThickness="1" VerticalAlignment="Center" HorizontalAlignment="Center" X1="0"
X2="{Binding ActualHeight, ElementName=PART_Clock, Converter={StaticResource DivisionConverter}, ConverterParameter=-2.5}">
<Line.Stroke>
<SolidColorBrush x:Name="MinuteStroke" Color="Black"/>
</Line.Stroke>
</Line>
<Line x:Name="PART_SecondHand" Visibility="{TemplateBinding ShowSeconds, Converter={StaticResource BooleanToVisibilityConverter}}" Stroke="Red" StrokeThickness="1" VerticalAlignment="Center" HorizontalAlignment="Center" X1="0"
X2="{Binding ActualHeight, ElementName=PART_Clock, Converter={StaticResource DivisionConverter}, ConverterParameter=-2.5}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Related

Animation of the TextBlock property defined in the template of the element (Buttons)

I apologize in advance for any mistakes, English is not my native.
<Style TargetType="{x:Type Button}" x:Key="LogOutButtonTheme">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Background= "{TemplateBinding Background}"
Width="{TemplateBinding Property=Width}"
Height="{TemplateBinding Property=Height}"
CornerRadius="10">
<Grid Width="{TemplateBinding Property=Width}"
Height="{TemplateBinding Property=Height}">
<TextBlock Text="{TemplateBinding Property=Content}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="18"></TextBlock>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
</Style.Setters>
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width"
To="85" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetProperty="Height"
To="45" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetProperty="Border.Grid.TextBlock.FontSize"
To="19" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width"
To="80" Duration="0:0:0.3" />
<DoubleAnimation Storyboard.TargetProperty="Height"
To="40" Duration="0:0:0.3" />
<DoubleAnimation Storyboard.TargetProperty="Border.Grid.TextBlock.FontSize"
To="18" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
I have a WPF style for a button with various animations, but these ones don't work:
<DoubleAnimation Storyboard.TargetProperty="Border.Grid.TextBlock.FontSize"
To="18" Duration="0:0:0.3" />
<DoubleAnimation Storyboard.TargetProperty="Border.Grid.TextBlock.FontSize"
To="19" Duration="0:0:0.3" />
My goal is to animate TextBlock's FontSize when the mouse enters or leaves the Button, but I don't know how to access a TextBlock's property which is defined like that:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="{TemplateBinding Background}" Width="{TemplateBinding Property=Width}" Height="{TemplateBinding Property=Height}" CornerRadius="10">
<Grid Width="{TemplateBinding Property=Width}" Height="{TemplateBinding Property=Height}">
<TextBlock Text="{TemplateBinding Property=Content}" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="18" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<FrameworkElement.Resources>
<Style TargetType="{x:Type Button}" x:Key="LogOutButtonTheme">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Background= "{TemplateBinding Background}"
Width="{TemplateBinding Property=Width}"
Height="{TemplateBinding Property=Height}"
CornerRadius="10">
<Grid Width="{TemplateBinding Property=Width}"
Height="{TemplateBinding Property=Height}">
<TextBlock x:Name="PART_TBlock" Text="{TemplateBinding Property=Content}" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="18"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" To="85" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetProperty="Height" To="45" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetProperty="FontSize" Storyboard.TargetName="PART_TBlock" To="19" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" To="80" Duration="0:0:0.3" />
<DoubleAnimation Storyboard.TargetProperty="Height" To="40" Duration="0:0:0.3" />
<DoubleAnimation Storyboard.TargetProperty="FontSize" Storyboard.TargetName="PART_TBlock" To="18" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
</Style.Setters>
</Style>
</FrameworkElement.Resources>
<Grid>
<Button Content="Кнопка" Style="{DynamicResource LogOutButtonTheme}"
Width="100" Height="60"/>
</Grid>
Note that if the button is not explicitly dimensioned, your animation will throw an exception.
You can also bind the font size of the TextBlock to the font size of the button.
And then you can animate the font size of the button.
<FrameworkElement.Resources>
<Style TargetType="{x:Type Button}" x:Key="LogOutButtonTheme">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Background= "{TemplateBinding Background}"
Width="{TemplateBinding Property=Width}"
Height="{TemplateBinding Property=Height}"
CornerRadius="10">
<Grid Width="{TemplateBinding Property=Width}"
Height="{TemplateBinding Property=Height}">
<TextBlock Text="{TemplateBinding Property=Content}" VerticalAlignment="Center" HorizontalAlignment="Center"
FontSize="{TemplateBinding FontSize}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
</Style.Setters>
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" To="85" Duration="0:0:0.2"/>
<DoubleAnimation Storyboard.TargetProperty="Height" To="45" Duration="0:0:0.2"/>
<DoubleAnimation Storyboard.TargetProperty="FontSize" To="19" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" To="80" Duration="0:0:0.3" />
<DoubleAnimation Storyboard.TargetProperty="Height" To="40" Duration="0:0:0.3" />
<DoubleAnimation Storyboard.TargetProperty="FontSize" To="18" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</FrameworkElement.Resources>
<Grid>
<Button Content="Кнопка" Style="{DynamicResource LogOutButtonTheme}"
Width="100" Height="60"/>
</Grid>

WPF Style Storyboard To Another Objects Value

Here I have a button style in appliction resources
<Style x:Key="ClickableText" TargetType="{x:Type Button}">
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="FontFamily" Value="/Tasks;component/Assets/Fonts/#Abel"/>
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<StackPanel VerticalAlignment="Center">
<ContentPresenter x:Name="Text" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Rectangle x:Name="Rect1" Width="{Binding ActualWidth, ElementName=Text}" Height="2" Fill="{DynamicResource LightGrey}"/>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In the style I have added a underlining rectangle to the text in the button.
<Rectangle x:Name="Rect1" Width="{Binding ActualWidth, ElementName=Text}" Height="2" Fill="{DynamicResource LightGrey}"/>
I have binded the rectangles width to be the same width as the text so that it adds a underline effect.
I now want to add an effect so that when you hover the button the rectangle reveals by spliting out.
I have got this far by adding this under the trigger tag
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.300" From="0" To="{Binding ActualWidth, ElementName=Text}" Storyboard.TargetName="Rect1" Storyboard.TargetProperty="Width" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.300" From="{Binding ActualWidth, ElementName=Text}" To="0" Storyboard.TargetName="Rect1" Storyboard.TargetProperty="Width" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
I want to link the to and from part of the double animation to the binding I used in the rectangle but it keeps producing errors. How can I do this effect?
I also want to use this as a reusable style I can distribute and keep in Application resources. I have seen other people do this through workarounds in code but am not sure if you can do this in application resources
Any help or guidance is greatly appriciated!!
LayoutTransform animation is Better for this effect.
I would do this animation in this way:
<Style x:Key="ClickableText" TargetType="{x:Type Button}">
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="FontFamily" Value="/Tasks;component/Assets/Fonts/#Abel"/>
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="MainBorder" Background="{TemplateBinding Background}">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="2"/>
</Grid.RowDefinitions>
<ContentPresenter x:Name="Text" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Rectangle x:Name="Rect1" Grid.Row="1" Height="2" Width="{Binding ElementName=Text, Path=ActualWidth}" Fill="LightGray">
<Rectangle.LayoutTransform>
<ScaleTransform ScaleX="0"/>
</Rectangle.LayoutTransform>
</Rectangle>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="MainBorder" Value="White"/>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Rect1" Storyboard.TargetProperty="(ContentPresenter.LayoutTransform).(ScaleTransform.ScaleX)" From="0" To="1" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Rect1" Storyboard.TargetProperty="(ContentPresenter.LayoutTransform).(ScaleTransform.ScaleX)" From="1" To="0" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>

WrapPanel ListBox not wrapping

I am trying to create a WrapPanel ListBox with a Button DataTemplate using this style:
<Style x:Key="lbxStyle" TargetType="ListBox">
<Setter Property="Background" Value="{StaticResource primaryBrush}"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="Margin" Value="6"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel
IsItemsHost="True"
Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Button>
<Button.Template>
<ControlTemplate TargetType="Button">
<Border
HorizontalAlignment="Left"
VerticalAlignment="Top"
BorderBrush="White"
Background="Transparent"
BorderThickness="2"
Margin="4,2,0,0">
<Border.Triggers>
<EventTrigger RoutedEvent="Border.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="
(Border.Background).
(SolidColorBrush.Color)"
From="Transparent"
To="{StaticResource accentColorTwo}"
Duration="0:0:0.25"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Border.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="
(Border.Background).
(SolidColorBrush.Color)"
From="{StaticResource accentColorTwo}"
To="Transparent"
Duration="0:0:0.25"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Border.Triggers>
<ContentPresenter
TextBlock.TextAlignment="Center"
TextBlock.Foreground="White"
TextBlock.FontFamily="SegoeUI"
TextBlock.FontSize="14"
Content="{Binding}"
Name="content"/>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
In the main window, it referenced like this:
<ListBox
x:Name="lbxUninspectedPrints"
Height="125"
Margin="16,0"
Style="{StaticResource lbxStyle}"
ItemsSource="{Binding UninspectedPrintList}"
SelectedValue="{
Binding DiePrintNav.SelectedDiePrintString,
Mode=OneWayToSource}"/>
But it does not want to wrap properly. Here is a screenshot:
So the trick was to move the width, height and alignment setters out of the border and into the button itself. I have made some other changes, but the working version of this list box is posted below (note that I had to move everything out of a style and put in inline with the ListBox reference due to binding issues).
<ListBox
Name="lbxUninspectedPrints"
Height="125"
Margin="16,0"
Background="{StaticResource primaryBrush}"
Foreground="White"
VerticalAlignment="Top"
VerticalContentAlignment="Top"
HorizontalContentAlignment="Left"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding UninspectedPrintList}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Button
DataContext="{Binding}"
Width="44"
Height="24"
VerticalAlignment="Top"
VerticalContentAlignment="Center"
HorizontalAlignment="Left"
HorizontalContentAlignment="Center"
Content="{Binding}"
Command="{
Binding DataContext.DiePrintNav.UninspectedPrintSelectedCommand,
RelativeSource={RelativeSource AncestorType=ListBox}}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Content}">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border
BorderBrush="White"
BorderThickness="2"
Background="Transparent">
<Border.Triggers>
<EventTrigger RoutedEvent="Border.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="
(Border.Background).
(SolidColorBrush.Color)"
From="Transparent"
To="{StaticResource accentColorTwo}"
Duration="0:0:0.25"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Border.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="
(Border.Background).
(SolidColorBrush.Color)"
From="{StaticResource accentColorTwo}"
To="Transparent"
Duration="0:0:0.25"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Border.Triggers>
<ContentPresenter
TextBlock.TextAlignment="Center"
TextBlock.Foreground="White"
TextBlock.FontFamily="SegoeUI"
TextBlock.FontSize="14"
Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Wpf button with both result datatrigger storyboard and mouseover background

I'm looking to implement this functionality: A button, bound to a command, that can signal back wether the command was successful in form of a red or green flash. At the same time, I want the button to look like other buttons.
This is the code I have now:
<Button IsEnabled="{Binding EmptyingAllowed}" Content="Töm lista" Foreground="#555555" FontWeight="SemiBold" Height="20" Width="65" Command="{Binding EmptyListCommand}" >
<Button.Style>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderBrush="#BBBBBB" Padding="1" BorderThickness="0,0,1,1" Background="#DDDDDD">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding ClearedOk}" Value="Ok">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation AccelerationRatio="0.2" DecelerationRatio="0.01" AutoReverse="True" Duration="0:0:1" To="LawnGreen" Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding ClearedOk}" Value="Error">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation AccelerationRatio="0.2" DecelerationRatio="0.01" AutoReverse="True" Duration="0:0:1" To="Red" Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
When the command is executed, ClearedOk is set to "Ok" or "Error" and then to "Empty", this causes the flash I'm looking for, unfortunately, the usual mouseOver-effect is lost for some reason, and if I add a mouseOver-trigger, it always takes precedence over the flashing effect, meaning the flash is only visible of the button isn't mouseOver:ed.
Is there a solution to this?
Try to make datatemplate and model with properties of state and then binding in template to this properties.
<DataTemplate x:Key="DataTemplate">
<Grid >
<Ellipse Stroke="White"
StrokeThickness="5"
Fill="{Binding State, Converter={StaticResource CheckToColorConverter}}"/>
</Grid>
</DataTemplate>

WPF error template border dont show all text

I have some error checkings in my WPF application. Error message is shown next to the textbox but when is the textbox at the right side of application, it doesnt show all error text.
The result:
This is mine error template style:
<ControlTemplate x:Key="errorTemplateStyle">
<StackPanel Orientation="Horizontal">
<Border BorderThickness="1" BorderBrush="#FFdc000c" CornerRadius="0.7"
VerticalAlignment="Top">
<Grid>
<Polygon x:Name="toolTipCorner"
Grid.ZIndex="2"
Margin="-1"
Points="6,6 6,0 0,0"
Fill="#FFdc000c"
HorizontalAlignment="Right"
VerticalAlignment="Top"
IsHitTestVisible="True"/>
<Polyline Grid.ZIndex="3"
Points="7,7 0,0" Margin="-1" HorizontalAlignment="Right"
StrokeThickness="1.5"
StrokeEndLineCap="Round"
StrokeStartLineCap="Round"
Stroke="White"
VerticalAlignment="Top"
IsHitTestVisible="True"/>
<AdornedElementPlaceholder x:Name="adorner"/>
</Grid>
</Border>
<Border x:Name="errorBorder" Background="#FFdc000c" Margin="1,0,0,0"
Opacity="0" CornerRadius="1.5"
IsHitTestVisible="False"
MinHeight="24" MaxWidth="267">
<Border.Effect>
<DropShadowEffect ShadowDepth="2.25"
Color="Black"
Opacity="0.4"
Direction="315"
BlurRadius="4"/>
</Border.Effect>
<TextBlock Text="{Binding ElementName=adorner,
Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"
Foreground="White" Margin="8,3,8,3" TextWrapping="Wrap"/>
</Border>
</StackPanel>
<ControlTemplate.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource BooleanOrConverter}">
<Binding ElementName="adorner" Path="AdornedElement.IsKeyboardFocused" />
<Binding ElementName="toolTipCorner" Path="IsMouseOver"/>
</MultiBinding>
</DataTrigger.Binding>
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="fadeInStoryboard">
<Storyboard>
<DoubleAnimation Duration="00:00:00.15"
Storyboard.TargetName="errorBorder"
Storyboard.TargetProperty="Opacity"
To="1"/>
<ThicknessAnimation Duration="00:00:00.15"
Storyboard.TargetName="errorBorder"
Storyboard.TargetProperty="Margin"
FillBehavior="HoldEnd"
From="1,0,0,0"
To="5,0,0,0">
<ThicknessAnimation.EasingFunction>
<BackEase EasingMode="EaseOut" Amplitude="2"/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="fadeInStoryboard"/>
<BeginStoryboard x:Name="fadeOutStoryBoard">
<Storyboard>
<DoubleAnimation Duration="00:00:00"
Storyboard.TargetName="errorBorder"
Storyboard.TargetProperty="Opacity"
To="0"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Can you help me how to show all error message?
Thanks Jakub
The solution is use popup for errorBorder.
Working style is:
<ControlTemplate x:Key="errorTemplateStyle">
<StackPanel Orientation="Horizontal">
<Border BorderThickness="1" BorderBrush="#FFdc000c" CornerRadius="0.7"
VerticalAlignment="Top">
<Grid>
<Polygon x:Name="toolTipCorner"
Grid.ZIndex="2"
Margin="-1"
Points="6,6 6,0 0,0"
Fill="#FFdc000c"
HorizontalAlignment="Right"
VerticalAlignment="Top"
IsHitTestVisible="True"/>
<Polyline Grid.ZIndex="3"
Points="7,7 0,0" Margin="-1" HorizontalAlignment="Right"
StrokeThickness="1.5"
StrokeEndLineCap="Round"
StrokeStartLineCap="Round"
Stroke="White"
VerticalAlignment="Top"
IsHitTestVisible="True"/>
<AdornedElementPlaceholder x:Name="adorner"/>
</Grid>
</Border>
<Popup x:Name="errorBorder" MinHeight="24" MinWidth="24" MaxWidth="267" Placement="Right" Margin="1,0,0,0" >
<Border Background="#FFdc000c"
Opacity="1" CornerRadius="1.5"
IsHitTestVisible="False"
MinHeight="24" MaxWidth="267">
<Border.Effect>
<DropShadowEffect ShadowDepth="2.25"
Color="Black"
Opacity="0.4"
Direction="315"
BlurRadius="4"/>
</Border.Effect>
<TextBlock Text="{Binding ElementName=adorner,
Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"
Foreground="White" Margin="8,3,8,3" TextWrapping="Wrap"/>
</Border>
</Popup>
</StackPanel>
<ControlTemplate.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource BooleanOrConverter}">
<Binding ElementName="adorner" Path="AdornedElement.IsKeyboardFocused" />
<Binding ElementName="toolTipCorner" Path="IsMouseOver"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter TargetName="errorBorder" Property="IsOpen" Value="True" />
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="fadeInStoryboard">
<Storyboard>
<DoubleAnimation Duration="00:00:00.15"
Storyboard.TargetName="errorBorder"
Storyboard.TargetProperty="Opacity"
To="1"/>
<ThicknessAnimation Duration="00:00:00.15"
Storyboard.TargetName="errorBorder"
Storyboard.TargetProperty="Margin"
FillBehavior="HoldEnd"
From="1,0,0,0"
To="5,0,0,0">
<ThicknessAnimation.EasingFunction>
<BackEase EasingMode="EaseOut" Amplitude="2"/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="fadeInStoryboard"/>
<BeginStoryboard x:Name="fadeOutStoryBoard">
<Storyboard>
<DoubleAnimation Duration="00:00:00"
Storyboard.TargetName="errorBorder"
Storyboard.TargetProperty="Opacity"
To="0"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>

Categories

Resources