Override application-wide style with a template in Silverlight - silverlight

I have a Silverlight application where I have styled my listboxes. This is a part of the style of the ListBoxItem, which is application-wide:
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ListBoxItemGrid" Storyboard.TargetProperty="Background" Duration="0">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource MouseOverColorBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
Now I have another listbox where I want nothing to happen when the user hovers over the ListBoxItem. I have tried this:
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver" />
</VisualStateGroup>
But that doesn't seem to work. How can I override the default, application-wide style? I'm not sure if it is relevant, but the application-wide style is a Style, while my 'special' listbox has a Template for its ListBoxItem.

Found it. I had to give the container a style:
<ListBox Grid.Row="1"
ItemsSource="{Binding TheItems}"
ItemContainerStyle="{StaticResource TheLineStyle}"
ItemTemplate="{StaticResource TheItemTemplate}"></ListBox>
<Style TargetType="ListBoxItem" x:Key="TheLineStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<ContentControl Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Related

Highlight selected bar in different color in wpf

I have a WPF application where I have a bar chart.
By default the color of bar is steel blue.
I want a functionality where when a users selects a bar, it should be highlighted in a different color i.e. red to indicate that is the product referring to. Please guide me how can I achieve this.
Currently I have used the following columndatapoint style.
<Style
x:Key="MyColumnDataPointStyle"
TargetType="charting:ColumnDataPoint">
<Setter Property="Background" Value="SteelBlue"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="charting:ColumnDataPoint">
<Border
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Opacity="1"
x:Name="Root">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.1"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MouseOverHighlight"
Storyboard.TargetProperty="Opacity"
To="0.6"
Duration="0"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.1"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Unselected"/>
<VisualState x:Name="Selected">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="SelectionHighlight"
Storyboard.TargetProperty="Opacity"
To="0.6"
Duration="0"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="RevealStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.5"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Shown">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="Root"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Hidden">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="Root"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid
Background="{TemplateBinding Background}">
<Rectangle>
<Rectangle.Fill>
<LinearGradientBrush>
<GradientStop
Color="#77ffffff"
Offset="0"/>
<GradientStop
Color="#00ffffff"
Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Border
BorderBrush="#ccffffff"
BorderThickness="1">
<Border
BorderBrush="#77ffffff"
BorderThickness="1"/>
</Border>
<Rectangle x:Name="SelectionHighlight" Fill="Red" Opacity="0"/>
<Rectangle x:Name="MouseOverHighlight" Fill="White" Opacity="0"/>
</Grid>
<ToolTipService.ToolTip>
<StackPanel>
<ContentControl
Content="{TemplateBinding FormattedIndependentValue}"
FontWeight="Bold"/>
<ContentControl
Content="{TemplateBinding FormattedDependentValue}"/>
</StackPanel>
</ToolTipService.ToolTip>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
To do this in the MVVM pattern I would create a ViewModel class for your ColumnDataPoint.
This ViewModel contains a bool property e.g. called IsActive.
You can then bind the bar's DataContext to that ViewModel and in your style you can set a DataTrigger bound to that property.
To change that property you can create a command in your ViewModel which will be executed when clicking the bar
Here is a small example:
<Rectangle Fill="SteelBlue"
DataContext="{Binding YourViewModel}">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Style.Triggers>
<DataTrigger Binding="{Binding IsActive}" Value="true">
<Setter Property="Stroke" Value="Chartreuse"/>
<Setter Property="StrokeThickness" Value="5"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<command:EventToCommand Command="{Binding ClickingBarCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Rectangle>
To use the "i" and "command" namespace you have to add
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:command="http://www.galasoft.ch/mvvmlight"
Hopefully this was helpful to you
cheers

WPF VisualStateManager.GoToState

I try to change the state for all the buttons in my program
I got this style for button:
<Style TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="StateMouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="UpperBorder" Duration="00:00:0.5" Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="#FF5086C4"/>
</Storyboard>
</VisualState>
<VisualState x:Name="StatePressed">
<Storyboard>
<ColorAnimation Storyboard.TargetName="UpperBorder" Duration="00:00:0.05" Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="#FF21214E"/>
</Storyboard>
</VisualState>
<VisualState x:Name="StateDisabled">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="UpperBorder" Duration="00:00:0.5" Storyboard.TargetProperty="(UIElement.Opacity)" To="0"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Lower" Cursor="Hand" BorderThickness="1" CornerRadius="4" Background="Gray" ></Border>
<Border MouseEnter="UpperBorder_MouseEnter" x:Name="UpperBorder" Cursor="Hand" CornerRadius="4" Background="#FF0657E8">
<Border.Effect>
<DropShadowEffect BlurRadius="10"/>
</Border.Effect>
</Border>
<ContentPresenter Cursor="Hand" Margin="8,8,8,8" HorizontalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
in this event: MouseEnter="UpperBorder_MouseEnter I want the change will take effect on all the buttons in my program (but the function VisualStateManager.GoToState take as parameter only spesific button)
how can I do that?
The button already have MouseOver state in CommonStates group. See Button Styles and Templates. The state auto set in the Button class when mouse over.
Is that what you want ?

Silverlight custom button

I've create a style for a button:
<Style x:Key="TicketOnBizOptionsButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimation Duration="0" To="#FFC0C0C0" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Storyboard.TargetName="border"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0" To="#FF14548C" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Storyboard.TargetName="border"/>
<ColorAnimation Duration="0" To="White" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="Content"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="border" BorderThickness="1" Background="#FFF2F2F2" CornerRadius="8" BorderBrush="#FFD5D5D5">
<Border.Effect>
<DropShadowEffect Direction="285" ShadowDepth="2" Color="#FFDFDFDF" BlurRadius="2"/>
</Border.Effect>
<Button Content="" Margin="-1" Width="105" BorderBrush="{x:Null}" Foreground="White" Background="{x:Null}" Opacity="0"/>
</Border>
<TextBlock x:Name="Content" Margin="5,5,5,5" Text="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The style works correctly and the button to.
But i've notice some erratic behavior when i click on the button.
Sometimes only works when clicking directly above the text other times only on the border...
The border that i've added has any effect on this??
Thanks in advance!
<Style x:Key="TicketOnBizOptionsButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimation Duration="0" To="#FFC0C0C0" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Storyboard.TargetName="border"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0" RepeatBehavior="1x" To="#FF14548C" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Storyboard.TargetName="border"/>
<ColorAnimation Duration="0" RepeatBehavior="1x" To="White" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="Content"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="border" BorderThickness="1" Background="#FFF2F2F2" CornerRadius="8" BorderBrush="#FFD5D5D5">
<Border.Effect>
<DropShadowEffect Direction="285" ShadowDepth="2" Color="#FFDFDFDF" BlurRadius="2"/>
</Border.Effect>
</Border>
<TextBlock x:Name="Content" Margin="5,5,5,5" Text="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The problem was that you were using a button in your template, so once you fired the pressed state it was causing some problems probably with the other button inside the template. I just removed the one inside de border and it worked well.
Hope it helps.

XAML - VisualGroupState for HyperlinkButton (whats wrong?)

Trying to figure out what I'm doing wrong (first time playing with Visual States). Can anyone point me to my problem? The app is crashing ungracefully, nothing else to help beyond that.
Heres the xaml
<Style TargetType="HyperlinkButton">
<Setter Property="Foreground" Value="{StaticResource HyperlinkTextBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="HyperlinkButton">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<ColorAnimation BeginTime="0" Duration="0.5"
Storyboard.TargetName="content"
Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)"
To="Red" />
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation BeginTime="0" Duration="0.5"
Storyboard.TargetName="content"
Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)"
To="White" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<ContentPresenter x:Name="content" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Thanks!
There is 3 places which you should correct:
1) The VisualStateManager.VisualStateGroups tag must be situated inside the root control like a Grid and not in the ControlTemplate.
2) The ContentPresenter class doesn't have the Foreground property. But this property exists in the ContentControl class. After you replace this control, add explicit bindings for the properties Content and Foreground.
3) The value of the Duration property should be in seconds. Although you can use the expression Duration="1" which means 1 day, the value 0.5 crashes the application. Half of a second looks like 0:0:0.5.
Here is the fixed style:
<Style TargetType="HyperlinkButton">
<Setter Property="Foreground" Value="{StaticResource HyperlinkTextBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="HyperlinkButton">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<ColorAnimation Duration="0:0:0.5"
Storyboard.TargetName="content"
Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)"
To="Red" />
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0:0:0.5"
Storyboard.TargetName="content"
Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)"
To="White" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl x:Name="content" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"
Foreground="{TemplateBinding Foreground}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

How to turn off animations in WPF Toolkit charts

Is there a way to turn off the animations in Xaml directly? The animations are really sluggish as my chart has many points.
i have downloaded the latest source code at http://wpf.codeplex.com/SourceControl/list/changesets
my idea is, to remove the animation by changing the style for the different chart series (chart points, DataPointStyle)
example for charting:PieDataPoint
try to remove the animation for the shown data and take your own style with a given key (x:key="myStyle" -> DataPointStyle="{StaticResource myStyle}")
and remove Opacity="0" at <Grid x:Name="Root" Opacity="0">
remove this visual state group from your style
<VisualStateGroup x:Name="RevealStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.5" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Shown">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="1" Duration="0" />
</Storyboard>
</VisualState>
<VisualState x:Name="Hidden">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="0" Duration="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
EDIT
This is the changed style.
<!-- charting:PieDataPoint -->
<Style TargetType="charting:PieDataPoint">
<Setter Property="Background" Value="Orange" />
<Setter Property="BorderBrush" Value="White" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="RatioStringFormat" Value="{}{0:p2}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="charting:PieDataPoint">
<Grid x:Name="Root" Opacity="0">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.1" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="MouseOverHighlight" Storyboard.TargetProperty="Opacity" To="0.6" Duration="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.1" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Unselected" />
<VisualState x:Name="Selected">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="SelectionHighlight" Storyboard.TargetProperty="Opacity" To="0.6" Duration="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Path x:Name="Slice" Data="{TemplateBinding Geometry}" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeMiterLimit="1">
<ToolTipService.ToolTip>
<StackPanel>
<ContentControl Content="{TemplateBinding FormattedDependentValue}" />
<ContentControl Content="{TemplateBinding FormattedRatio}" />
</StackPanel>
</ToolTipService.ToolTip>
</Path>
<Path x:Name="SelectionHighlight" Data="{TemplateBinding GeometrySelection}" Fill="Red" StrokeMiterLimit="1" IsHitTestVisible="False" Opacity="0" />
<Path x:Name="MouseOverHighlight" Data="{TemplateBinding GeometryHighlight}" Fill="White" StrokeMiterLimit="1" IsHitTestVisible="False" Opacity="0" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
After my first attempt to remove the animation, I wanted to give up, because it has not worked.
But then I looked upon me with the reflector to the source code and have found a way that it still works.
Setting the DataPointStyle unfortunately is not enough, I think it's a bug.
<chartingToolkit:Chart Margin="8">
<chartingToolkit:Chart.Series>
<chartingToolkit:BarSeries x:Name="barSeries"
Title="Experience"
DataPointStyle="{StaticResource myBarStyle}">
</chartingToolkit:BarSeries>
</chartingToolkit:Chart.Series>
</chartingToolkit:Chart>
In the constructor of the control where the chart is included simply execute the following.
this.barSeries.RefreshStyles();
hope this helps

Resources