Binding event handlers to the templated hyperlink - wpf

I created a templated hyperlinkbutton in wpf (windows 8 metro app):
<ControlTemplate TargetType="HyperlinkButton">
<HyperlinkButton>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition To="PointerOver" GeneratedDuration="0:0:0.1"/>
</VisualStateGroup.Transitions>
</VisualStateGroup>
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="HyperlinkForegroundBrush" Storyboard.TargetProperty="Color" To="#FF011751"/>
</Storyboard>
</VisualState>
</VisualStateManager.VisualStateGroups>
<ContentPresenter Content={TemplateBinding Content}>
<ContentPresenter.Foreground>
<SolidColorBrush x:Name="HyperlinkForegroundBrush" Color="3FFB20404"/>
</ContentPresenter.Foreground>
</ContentPresenter>
</HyperlinkButton>
and this is the hyperlinkbutton::
<HyerlinkButton Style={StaticResource MainPageLinkStyle} x:Name="MoreDetailsHyperlinkButton" Content="More..." Click="MoreDetailsHyperlinkButton_Click"/>
The style MainPageLinkStyle refers to the above style mentioned.
Problem: The click of the hyperlinkbutton doesn't gets executed.
Please help.
Thanks in advance.
EDIT:
Instead of hyperlinkbutton's click event, when I use PointerPressed event, the mouse right click triggers this event,but not the mouse left click....Seems strange to me.

I found the solution. Here's the modified markup:
<ControlTemplate TargetType="HyperlinkButton">
<**Border**>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition To="PointerOver" GeneratedDuration="0:0:0.1"/>
</VisualStateGroup.Transitions>
</VisualStateGroup>
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="HyperlinkForegroundBrush" Storyboard.TargetProperty="Color" To="#FF011751"/>
</Storyboard>
</VisualState>
</VisualStateManager.VisualStateGroups>
<ContentPresenter Content={TemplateBinding Content}>
<ContentPresenter.Foreground>
<SolidColorBrush x:Name="HyperlinkForegroundBrush" Color="3FFB20404"/>
</ContentPresenter.Foreground>
</ContentPresenter>
</**Border**>
As highlighted in the markup, I need to use Border class instead of Hyperlink. I am not able to understand why, but this seems to be a possible solution working for me.

Related

Wpf Visual transitions not working as intended

I am trying to create a custom button using a template.
I have written this template:
<Style TargetType="Button" x:Key="Delete Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition To="MouseOver"
GeneratedDuration="0:0:1"/>
<VisualTransition To="Pressed"
GeneratedDuration="0:0:1"/>
<VisualTransition From="Presse To="MouseOver"
GeneratedDuration="0:0:1"/>
<VisualTransition To="Normal"
GeneratedDuration="0:0:1"/>
<VisualTransition To="Disabled"
GeneratedDuration="0:0:0.1"/>
<VisualTransition From="Disabled"
GeneratedDuration="0:0:0.1"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="VisPres"
Storyboard.TargetProperty="Stroke.Color"
To="PaleVioletRed"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Storyboard.TargetName="VisPres"
Storyboard.TargetProperty="Fill.Color"
To="DarkRed">
</ColorAnimation>
<ColorAnimation Storyboard.TargetName="VisPres"
Storyboard.TargetProperty="Stroke.Color"
To="Red"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimation Storyboard.TargetName="VisPres"
Storyboard.TargetProperty="Fill.Color"
To="Gray"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Ellipse x:Name="VisPres" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Fill="Red"
Stroke="Black" StrokeThickness="4">
</Ellipse>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="4,4,4,4"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The template looks fine, but all the animation transitions take 1 seond, even though I stated they should take different times in the visualtransition.
can anyone help me please?
thank you very much!
Edit: here is another template on which even increasing times won't work
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition To="MouseOver"
GeneratedDuration="0:0:0.2"/>
<VisualTransition To="Pressed"
GeneratedDuration="0:0:0.01"/>
<VisualTransition From="Pressed" To="MouseOver"
GeneratedDuration="0:0:0.01"/>
<VisualTransition To="Normal"
GeneratedDuration="0:0:2"/>
<VisualTransition To="Disabled"
GeneratedDuration="0:0:0"/>
<VisualTransition From="Disabled" To="Normal"
GeneratedDuration="0:0:2"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="LightCol"
Storyboard.TargetProperty="Color"
To="#BCFF8E"/>
<ColorAnimation Storyboard.TargetName="ShadCol"
Storyboard.TargetProperty="Color"
To="#A1CC84"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Storyboard.TargetName="LightCol"
Storyboard.TargetProperty="Color"
To="#72E324"/>
<ColorAnimation Storyboard.TargetName="ShadCol"
Storyboard.TargetProperty="Color"
To="#6CBF32"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimation Storyboard.TargetName="LightCol"
Storyboard.TargetProperty="Color"
To="Gray"/>
<ColorAnimation Storyboard.TargetName="ShadCol"
Storyboard.TargetProperty="Color"
To="Gray"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="Focused">
<Storyboard>
<ThicknessAnimation Storyboard.TargetName="Bord"
Storyboard.TargetProperty="BorderThickness"
To="2"
Duration="0:0:0"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Bord" BorderBrush="Blue" BorderThickness="0">
<Rectangle Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop x:Name="LightCol" Color="#D7FFBC" Offset="0.499"/>
<GradientStop x:Name="ShadCol" Color="#D5E5CA" Offset="0.501"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Border>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="4,4,4,4"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

WPF Slider VisualStateManager

I'm trying to do my own Slider Style in XAML, but i don't get it quite right. The VisualState x:Name="Pressed" is not being triggered.
...
<ControlTemplate TargetType="Slider">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal" />
<VisualState Name="MouseOver">
...
</VisualState>
<VisualState Name="Pressed">
<Storyboard>
<ColorAnimation Storyboard.TargetName="RepeatButtonValueBrush" Storyboard.TargetProperty="Color" To="{StaticResource PressedValueColor}" Duration="0"/>
<ColorAnimation Storyboard.TargetName="RepeatButtonRestBrush" Storyboard.TargetProperty="Color" To="{StaticResource PressedTrackColor}" Duration="0"/>
</Storyboard>
</VisualState>
<VisualState Name="Disabled">
...
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
...
</Grid>
</ControlTemplate>
...
What am I doing wrong?
Thanks
You need to call the VisualStateManager.GoToState method to change visual states. See this VisualStateManager and Triggers article.

VisualStateManager Commonstate overrides other state specified in Silverlight 4

<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="00:00:00.1000000"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal">
</VisualState>
<VisualState x:Name="Focused">
</VisualState>
<VisualState x:Name="Pressed">
</VisualState>
<VisualState x:Name="MouseOver">
</VisualState>
<VisualState x:Name="Selected">
</VisualState>
</VisualStateGroup>
I have xaml as above i am programmatically applying Selected state by using VisualStateManager.GoToState and after applying it again i do mouse over it then it applies MouseOver styles How do i prevent overriding of style?
if you want separate viewstates you have to separate them into separate visualstategroups. Any Visual state in the same visualstate group can override any other visual state in the same group.
So if you dont want mouseover to override selected you have to put them in separate groups.

Override application-wide style with a template in 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>

Animate Margin values between states in WPF

I'm trying to familiarize myself with WPF for an upcoming project. I'm having problem animating margins between states. Using Blend I've obtained the following sample XAML. If I trigger the state "Large" from codebehind, the rectangle suddenly expands after 1 second, instead of "easing" into the expansion, which is the desired effect.
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:1"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Large">
<Storyboard>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="rectangle">
<EasingThicknessKeyFrame KeyTime="0" Value="64,135,47,191"/>
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="rectangle" Fill="#FFF4F4F5" Margin="428,135,47,191" Stroke="Black"/>
</Grid>
Thanks in advance!
I think it is because you only have one keyframe set to 0 in your animation.
try this :
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<!--Take one second to transition to the Large state.-->
<VisualTransition To="Large" GeneratedDuration="0:0:1"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal" />
<!--Change the Margin to "64,135,47,191" when the states gets to "Large"-->
<VisualState x:Name="Large">
<Storyboard>
<ThicknessAnimation Storyboard.TargetName="rectangle" Storyboard.TargetProperty="Margin" To="64,135,47,191" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="rectangle" Margin="428,135,47,191" Fill="#FFF4F4F5" Stroke="Black"/>
</Grid>
edit: I was not very pleased with my first shot, so here is a better way of doing this.

Resources