TabItem Storyboard affects neighboring TabItems - wpf

We have a TabItem Style which contains a very simple ControlTemplate:
<Border x:Name="border" BorderThickness="0" Background="{DynamicResource MediumGray}" Margin="0,0,1,1"
SnapsToDevicePixels="True" TextBlock.Foreground="{DynamicResource DarkGray}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{TemplateBinding Header}" />
</Border>
The ControlTemplate contains an EventTrigger which fires on MouseEnter. The storyboard uses a ColorAnimation:
<Storyboard>
<ColorAnimation To="{StaticResource _LightGray}" BeginTime="0:00:00"
Duration="0:00:00.200"
Storyboard.TargetName="border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" />
</Storyboard>
The Storyboard works as expected - except that it also affects the other TabItems in the TabControl. They all animate to the target color.

Moving the original background brush in to a ControlTemplate Resource cleared this issue:
<ControlTemplate TargetType="{x:Type TabItem}">
<ControlTemplate.Resources>
<SolidColorBrush x:Key="borderBackground" Color="{StaticResource _MediumGray}" />
</ControlTemplate.Resources>
<Border Background="{StaticResource borderBackground}" ... />
</ControlTemplate>

Related

WPF Highlight brush for Combobox template

I can't figure out how to set the Highlight brush of a Combobox (the color that will mark the item being selected on mouse over) to a certain Brush. I have used Edit Template -> Copy to get copy of the template where I try to set the SystemColors.HighlightBrushKey. I have seen answers that one should be able to set the brush by defining it like this in the Style resource, but it just does not work.
I have also tried to set the Grid's Style.Resource in which the comobox is placed, that did not help either.
Please see line 3 and line 15 where I set the color to red. No effect. What am I doing wrong?
<Style x:Key="TeachpendantVMVisionServerComboBoxStyle" TargetType="{x:Type ComboBox}">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Red" />
</Style.Resources>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid x:Name="grid">
<Grid.Style>
<Style>
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Red" />
</Style.Resources>
</Style>
</Grid.Style>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition MaxWidth="18"/>
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ValidationStates">
<VisualState x:Name="Valid"/>
<VisualState x:Name="InvalidFocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush)" Storyboard.TargetName="PART_EditableTextBox">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="Red"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill)" Storyboard.TargetName="path">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource MoveTextBox.Invalid.BorderBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="toggleButton">
<EasingColorKeyFrame KeyTime="0" Value="#FFFB0000"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="InvalidUnfocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush)" Storyboard.TargetName="PART_EditableTextBox">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource MoveTextBox.Invalid.BorderBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="toggleButton">
<EasingColorKeyFrame KeyTime="0" Value="Red"/>
</ColorAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill)" Storyboard.TargetName="path">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="Red"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TextBox x:Name="PART_EditableTextBox"
Padding="5,0,0,0"
Height="{TemplateBinding Height}">
<TextBox.Template>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border
x:Name="border"
CornerRadius="3,0,0,3"
BorderThickness="1,1,0,1"
Background="{DynamicResource Button.Static.Background}"
BorderBrush="{DynamicResource Button.Static.Background}">
<ScrollViewer x:Name="PART_ContentHost"/>
</Border>
</Grid>
</ControlTemplate>
</TextBox.Template>
</TextBox>
<ToggleButton x:Name="toggleButton" Grid.Column="1" Margin="0"
Height="{TemplateBinding Height}"
Focusable="False"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press" BorderBrush="#FFABADB3">
<ToggleButton.Template>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border
Background="{DynamicResource Button.Checked.Background}"
x:Name="border"
CornerRadius="0,3,3,0"
BorderThickness="0,1,1,1"
BorderBrush="{DynamicResource Button.Static.Background}">
<ContentPresenter />
</Border>
</ControlTemplate>
</ToggleButton.Template>
<Path x:Name="path" Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z"
Fill="Gold" />
</ToggleButton>
<ContentPresenter x:Name="ContentSite"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Margin="5,0,0,0" RecognizesAccessKey="True"/>
<Popup x:Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="True"
PopupAnimation="Slide"
OverridesDefaultStyle="True">
<Grid x:Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border
x:Name="DropDownBorder"
BorderThickness="1"
CornerRadius="5"
Background="Azure"
BorderBrush="DarkGray">
</Border>
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate/>
</Setter.Value>
</Setter>
</Style>
It was fairly simple after all (but not obvious where to find it).
Just edit a copy of the ItemsContainerStyle and all these Brushes can be set from there.
To Change the layout of the ComboBox (creating a round combobox or changing colors)
Style="{DynamicResource MyComboBoxStyle}"
To Change the hoover and selected Highlight colors
ItemContainerStyle="{DynamicResource MyComboBoxItemS}"
The complete Combobox would look like this then in XAML
<ComboBox x:Name="positionsComboBox"
Grid.Column="1"
Grid.ColumnSpan="3"
IsReadOnly = "True"
IsEditable = "False"
Margin="3,0,3,0"
ItemsSource="{Binding IDs, Source={StaticResource Locator}, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
SelectedValue="{Binding SelectedID, Source={StaticResource Locator}, Mode=TwoWay}"
Style="{DynamicResource MyComboBoxStyle}"
IsSynchronizedWithCurrentItem="True"
ItemContainerStyle="{DynamicResource MyComboBoxItemContainerStyle}"
FontWeight="Bold"
FontSize="24"/>

How to avoid that a Coloranimation in a ControlTemplate gets applied to every object using the template

I declared ColorAnimations inside a ControlTemplate of a Style.
What it should do:
Whenever the mouse hovers over the object the color of this specific object should be animated.
What it does instead:
Animating the color of EVERY object the style is applied to whenever I hover over one of them, even though the property activating the animation is not changing on all objects.
What I tried before:
I tried using an Eventrigger instead of a normal trigger but the problem persists.
I also tried using the "Name" property not "x:Name" but this didn't help either.
Also not using Storyboard.TargetName but Storyboard.Target and using a binding with RelativeSource to let it find the object.. and still every object using this style gets animated whenever I hover over any of them
It works as intended if I use Setters to change the background instead of Storyboards and ColorAnimations.
The Style
<Style x:Key="Fraction_ScrollViewer_ScrollBar_Thumb" TargetType="{x:Type Thumb}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border
x:Name="Border"
CornerRadius="5"
Background="{TemplateBinding Background}"
BorderThickness="0" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard
Name="IsMouseOver_True"
HandoffBehavior="Compose">
<Storyboard>
<ColorAnimation
Storyboard.TargetName="Border"
Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
To="{StaticResource 'Color_CoolGrey'}"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard
Name="IsMouseOver_False">
<Storyboard>
<ColorAnimation
Storyboard.TargetName="Border"
Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
To="{StaticResource 'Color_MidGrey'}"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
The Thumb style is used in a Scrollbar style which is used in a ScrollViewer.
The Scrollviewer Style is then used in 2 locations:
1:
<Style x:Key="LabelTreeView" TargetType="{x:Type TreeView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeView}">
<ScrollViewer
Style="{StaticResource ScrollViewer}"
Focusable="False"
CanContentScroll="False"
Padding="4">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
2:
<ScrollViewer
Style="{StaticResource ScrollViewer}"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<ItemsControl
BorderThickness="0"
Background="{StaticResource Brush_Transparent}"
ItemTemplate="{StaticResource CharacterSequenceChar}"
ItemsSource="{Binding DisplayedCharacterSequenceCharacters}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
What is causing this behaviour and how to avoid it with still using animations?
Apparently all Buttons share the same Brush instance in their Background property.
You could explicitly assign a separate Brush for each Border in the Template:
<Border x:Name="Border" ...>
<Border.Background>
<SolidColorBrush Color="{Binding Background.Color,
RelativeSource={RelativeSource TemplatedParent}}"/>
</Border.Background>
</Border>

WPF Something overriding tab content alignment of TabControl

I used this as a starting point to make a style for a TabControl, mine only works with TabStripPlacement="Bottom". I expect that the content I put in the TabItem would fill the entire area, designated for it, like it does with the default style and the style from microsoft I used as a starting point. But it does not, It starts with its minimal sizes, buttons don't get stretched at all and RichTextBoxes seem stretched only horizontally, if I add text to the RichTextBox it expands. Here is what it looks like:
The orange is the area I expect the content to take (with some margins), the blue is the background of the RichTextBox. The green is the global background. The selected tab has its header's border thickened (red). Don't mind the space between the tab headers and the content area, it is intentional.
I've been poking around a lot, but can't seem to find the cause, however I have found that I don't have this problem if I don't apply the style for the TabItem. And when I inspect the elements with the xaml debugging tools in visual studio I find that PART_SelectedContentHost has its horizontal alignment set to Left and vertical alignment set to Top, happens even if I have explicitly set them to Stretch in the style. I also tried applying "Stretch" to the RichTextBox, it didn't work. Here is the style:
<Style TargetType="{x:Type TabControl}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid KeyboardNavigation.TabNavigation="Local" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="30" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="#FFAAAAAA" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TabPanel x:Name="HeaderPanel"
Grid.Row="2"
Panel.ZIndex="1"
Margin="0"
IsItemsHost="True"
KeyboardNavigation.TabIndex="1"
Background="Transparent" />
<Border x:Name="Border"
Grid.Row="0"
Panel.ZIndex="0"
BorderThickness="0"
CornerRadius="0"
KeyboardNavigation.TabNavigation="Local"
KeyboardNavigation.DirectionalNavigation="Contained"
KeyboardNavigation.TabIndex="2"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch">
<Border.Background>
<SolidColorBrush Color="Orange"/>
</Border.Background>
<ContentPresenter
x:Name="PART_SelectedContentHost"
Margin="4,4,4,4"
ContentSource="SelectedContent"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type TabItem}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid x:Name="Root">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected" />
<VisualState x:Name="Selected">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ContentSite"
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
From="White" To="Blue"
Duration="0:0:0.0" AutoReverse="True"/>
<ThicknessAnimationUsingKeyFrames
Storyboard.TargetProperty="(Border.BorderThickness)"
Storyboard.TargetName="Border">
<EasingThicknessKeyFrame KeyTime="0"
Value="1,5,1,5" />
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver" />
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border"
Margin="0,0,0,0"
BorderThickness="1,1,1,1"
CornerRadius="0,0,0,0"
BorderBrush="Red">
<Border.Background>
<SolidColorBrush Color="Black"/>
</Border.Background>
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="12,2,12,2"
RecognizesAccessKey="True"
TextBlock.Foreground="White"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Panel.ZIndex" Value="100"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
EDIT: For the sake clarity, the style is saved in a xaml file - "TabControlStyleDictionary.xaml" and this is the code of the main window:
<Window x:Class="TabControlStylingTest2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TabControlStylingTest2"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="TabControlStyleDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid Background="Green">
<TabControl TabStripPlacement="Bottom">
<TabItem Header="tab1">
<RichTextBox
Foreground="White"
Background="Blue"
AcceptsReturn="True"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"/>
</TabItem>
<TabItem Header="tab2">
<Button
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
some text 123456789
</Button>
</TabItem>
</TabControl>
</Grid>
I had the same issue with overwriting the style. For some reason the HorizontalAlignment and VerticalAlignment properties of the ContentPresenter are set locally on each LayoutUpdate of the PART_SelectedContentHost in the codebehind. In my solution I implement an Attached Behavior for UIElements which calls the ClearValue method on a LayoutUpdate event. This will delete the local value on each occurance of the event. A refrence to System.Windows.Interactivity is required for this.
public class ClearValueOnLayoutUpdateBehavior : Behavior<UIElement>
{
public static readonly DependencyProperty PropertyProperty =
DependencyProperty.Register(nameof(Property), typeof(DependencyProperty), typeof(ClearValueOnLayoutUpdateBehavior), new PropertyMetadata());
public DependencyProperty Property
{
get { return (DependencyProperty)GetValue(PropertyProperty); }
set { SetValue(PropertyProperty, value); }
}
protected override void OnAttached()
{
base.OnAttached();
if(Property != null)
AssociatedObject.LayoutUpdated += AssociatedObject_LayoutUpdated;
}
private void AssociatedObject_LayoutUpdated(object sender, EventArgs e)
{
AssociatedObject.ClearValue(Property);
}
}
In your XAML file you have to add the xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" reference as well. Your ContentPresenter should be changed as following:
<ContentPresenter
x:Name="PART_SelectedContentHost"
ContentSource="SelectedContent"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<i:Interaction.Behaviors>
<behavior:ClearValueOnLayoutUpdateBehavior Property="{x:Static FrameworkElement.HorizontalAlignmentProperty}" />
<behavior:ClearValueOnLayoutUpdateBehavior Property="{x:Static FrameworkElement.VerticalAlignmentProperty}" />
</i:Interaction.Behaviors>
</ContentPresenter>

ProgressBar Theme with diagonal lines decorator

I want to decorate the WPF ProgressBar like the image below:
Current:
Decorated:
Also, those blank diagonal lines should move in marquee animation from left to right. At the moment i have this simple Style for the current appearance:
<Style x:Key="{x:Type ProgressBar}" TargetType="{x:Type ProgressBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Border x:Name="BorderBackground" CornerRadius="3" BorderThickness="1" BorderBrush="{StaticResource ProgressBarBorderBrush}" Background="{StaticResource ProgressBarBackgroundBrush}">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Determinate" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="PART_Track" Margin="2" BorderThickness="1" CornerRadius="2" />
<Border x:Name="PART_Indicator" Margin="2" BorderThickness="1" CornerRadius="2" HorizontalAlignment="Left" Background="{StaticResource ProgressBarTrackBackgroundBrush}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Anyone can help me to get it? I searched for it but maybe i missed the correct keywords to find something like this, at least i usually see (like at OS X progressbar) that this "decoration" is usually used.
Thanks in advance ;).
Solution template with the answer code a bit modified:
<Style x:Key="{x:Type ProgressBar}" TargetType="{x:Type ProgressBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Border x:Name="BorderBackground" CornerRadius="3" BorderThickness="1" BorderBrush="{StaticResource ProgressBarBorderBrush}" Background="{StaticResource ProgressBarBackgroundBrush}" Effect="{StaticResource LightStrongDownLinearShadowEffect}">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Determinate" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="PART_Track" Margin="2" BorderThickness="1" CornerRadius="2" />
<Border x:Name="PART_Indicator" Margin="2" BorderThickness="1" CornerRadius="2" HorizontalAlignment="Left" Background="{StaticResource ProgressBarTrackBackgroundBrush}" ClipToBounds="True">
<Border x:Name="DiagonalDecorator" Width="5000">
<Border.Background>
<DrawingBrush TileMode="Tile" Stretch="None" Viewbox="0,0,1,1" Viewport="0,0,25,25" ViewportUnits="Absolute">
<DrawingBrush.RelativeTransform>
<TranslateTransform X="0" Y="0" />
</DrawingBrush.RelativeTransform>
<DrawingBrush.Drawing>
<GeometryDrawing Brush="#20FFFFFF" Geometry="M10,0 22,0 12,25 0,22 Z" />
</DrawingBrush.Drawing>
</DrawingBrush>
</Border.Background>
<Border.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Border.Background).(DrawingBrush.RelativeTransform).(TranslateTransform.X)" From="0" To=".25" RepeatBehavior="Forever" Duration="0:0:15" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
</Border>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Edit:
This article from codeproject.com has a working version of the "barber pole" progress bar. Search the article for "CandyCaneProgressPainter".
Previous answer:
This does almost exactly what you want. All you have to do to make it what you want is restrict the visibility of the rectangle to the percentage you want and change the height/width ratio.
The keywords you want are "storyboard", "animate" and "trigger"
Here is the xaml from the link with some comments from the link on making the animation smooth:
<Rectangle x:Name="pole" Width="100" Height="20" Stroke="Black" StrokeThickness="1">
<Rectangle.Fill>
<DrawingBrush TileMode="Tile" Stretch="None" Viewbox="0,0,1,1" Viewport="0,0,25,25" ViewportUnits="Absolute">
<DrawingBrush.RelativeTransform>
<TranslateTransform X="0" Y="0" />
</DrawingBrush.RelativeTransform>
<DrawingBrush.Drawing>
<GeometryDrawing Brush="Red" Geometry="M10,0 25,0 15,25 0,25 Z" /> </DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Rectangle.Fill).(DrawingBrush.RelativeTransform).(TranslateTransform.X)" From="0" To=".25" RepeatBehavior="Forever" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
I guess the jerking happens if you remove the "width" value, but if the value is put back it runs smooth. Weird.
Yup, indeed it basically needed a few adjustments with the multiples of the number rules the width in this case the animation can be a .1 or a .05 if for instance you have a 5000 width.... now it work great!
In your PART_Indicator border embed a Compound Path of the shapes to make the diagonal lines. You're going to have to kind of fake the Marquee effect to get the scrolling diagonal lines however unless you want to use a jquery plugin or other alternative.
However what you CAN do in pure xaml is create the diagonal line paths, make lots and lots of them to make the row of diagnol lines very very long. Since they're embedded in the indicator border they're only visible within it.
Now create a new storyboard animation and use a ControlStoryboardAction Behavior to trigger it onload and set it to repeat. Grab the diagonal lines compound path an choose a keyframe on your timeline a ways out from the start frame, then drag the Compound Path of diagonal lines to one side or set a large Margin to the left so during the animation sequence it moves to the right. The idea is its a visual hoax. Your diagonal lines will just act as an animation storyboard that only mimics the marquee animation. So those lines will still move across the bar and hopefully theres enough of them the animation doesnt repeat before the content is loaded. Hopefully this makes sense haha. It takes some tweaking but you can result in a decent solution. Best of luck!
This post is quite old, but I just faced the same problem and got a nice solution I would like to share:
<SolidColorBrush x:Key="ProgressBarBackgroundBrush" Color="Gray" />
<SolidColorBrush x:Key="ProgressBarTrackBackgroundBrush" Color="#105295" />
<Style x:Key="{x:Type ProgressBar}" TargetType="{x:Type ProgressBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<controls:RoundBorder x:Name="BorderBackground" CornerRadius="3" BorderThickness="0"
BorderBrush="{StaticResource ProgressBarBorderBrush}"
Background="{StaticResource ProgressBarBackgroundBrush}">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Determinate" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="PART_Track" Margin="0" BorderThickness="0" CornerRadius="3" />
<Border x:Name="PART_Indicator" Margin="0" BorderThickness="0" CornerRadius="3" HorizontalAlignment="Left"
Background="{StaticResource ProgressBarTrackBackgroundBrush}" ClipToBounds="True">
<Border x:Name="DiagonalDecorator" Width="5000">
<Border.Background>
<DrawingBrush TileMode="Tile" Stretch="None" Viewbox="0,0,1,1" Viewport="0,0,36,34" ViewportUnits="Absolute">
<DrawingBrush.RelativeTransform>
<TranslateTransform X="0" Y="0" />
</DrawingBrush.RelativeTransform>
<DrawingBrush.Drawing>
<GeometryDrawing Brush="#156dc7" Geometry="M0,0 18,0 36,34 18,34 Z" />
</DrawingBrush.Drawing>
</DrawingBrush>
</Border.Background>
<Border.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Border.Background).(DrawingBrush.RelativeTransform).(TranslateTransform.X)"
From="0" To=".36" RepeatBehavior="Forever" Duration="0:0:18" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
</Border>
</Border>
</Grid>
</controls:RoundBorder >
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Silverlight ScrollViewer - fade in\out the scrollbar

I have a scrollviewer and I want to animate the way the vertical scrollbar appears. The scrollbar is set to AUTO , so I want it to fade in when needed and fade out when not needed.
I know how to drill into templates and change colors and appearance, but can I make a change like this ?
This was a fun question. Since Scrollbar and ScrollViewer are sealed this was a bit of a challenge. (I thought of making a copy of ScrollViewer using Reflector, but here is a XAML-only solution).
When I heard animation, I thought states. It would have been nice if ScrollViewer was implemented using states, but unfortunately, it was not. By using DataStateBehavior, we can create states out of a property -- in this case, states for the ComputedVerticalScrollBarVisibility property. For some reason, it didn't work to bind the DataStateBehavior to the ScrollViewer's ComputedVerticalScrollBarVisibility using TemplateBinding. (Anyone know why?) I was able to bind it to the VerticalScrollbar Visibility property, but I decided not to:
In order for the Fade out to work, I didn't want the VerticalScrollbar.Visibility to still be bound to ComputedVerticalScrollBarVisibility because if it was, the scrollbar would immediately disapper when the property changed. Instead, I used the VerticalScrollbar Tag property to hold the ComputedVerticalScrollBarVisibility and bound the DataStateBehavior to the VerticalScrollbar Tag.
Now that states are in place, it was an easy matter to set the Opacity for each state and the state transition duration and, voila!, you have a fade in ScrollViewer.
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" x:Class="SilverlightApplication5.MainPage"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<Style x:Key="ScrollViewerStyle1" TargetType="ScrollViewer">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="VerticalScrollBarVisibility" Value="Visible"/>
<Setter Property="Padding" Value="4"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFA3AEB9" Offset="0"/>
<GradientStop Color="#FF8399A9" Offset="0.375"/>
<GradientStop Color="#FF718597" Offset="0.375"/>
<GradientStop Color="#FF617584" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.5"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="VerticalVisible">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="VerticalScrollBar" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
<VisualState x:Name="VerticleHidden">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="VerticalScrollBar" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Background="{TemplateBinding Background}">
<i:Interaction.Behaviors>
<ei:DataStateBehavior Binding="{Binding Tag, ElementName=VerticalScrollBar}" Value="Visible" TrueState="VerticalVisible" FalseState="VerticleHidden"/>
</i:Interaction.Behaviors>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollContentPresenter x:Name="ScrollContentPresenter" Cursor="{TemplateBinding Cursor}" ContentTemplate="{TemplateBinding ContentTemplate}" Margin="{TemplateBinding Padding}"/>
<Rectangle Grid.Column="1" Fill="#FFE9EEF4" Grid.Row="1"/>
<ScrollBar x:Name="VerticalScrollBar" Grid.Column="1" IsTabStop="False" Maximum="{TemplateBinding ScrollableHeight}" Margin="0,-1,-1,-1" Minimum="0" Orientation="Vertical" Grid.Row="0" Tag="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{TemplateBinding VerticalOffset}" ViewportSize="{TemplateBinding ViewportHeight}" Width="18"/>
<ScrollBar x:Name="HorizontalScrollBar" Grid.Column="0" Height="18" IsTabStop="False" Maximum="{TemplateBinding ScrollableWidth}" Margin="-1,0,-1,-1" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{TemplateBinding HorizontalOffset}" ViewportSize="{TemplateBinding ViewportWidth}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="Beige">
<ScrollViewer VerticalScrollBarVisibility="Auto" Style="{StaticResource ScrollViewerStyle1}">
<Rectangle Margin="10" Fill="LightBlue" MinHeight="300" />
</ScrollViewer>
</Grid>
</UserControl>
To see this in action, run this code and shrink the browser window. The scrollbar will fade into view.

Resources