Why is my XAML button PointerOver VisualState not working? - xaml

I am trying to get the following PointerOver VisualState to work. Ideally when the mouse pointer is over the button, I want to highlight the button with a black border.
I have been trying various ways to make this work, please help.
Note: If I set the BorderColor value of the BorderHighlight, Border element, I get the border desired, but not when I made it as part of the VisualState.
<Style x:Key="SecondaryButton" TargetType="Button">
<Setter Property="Background" Value="LightSkyBlue"></Setter>
<Setter Property="Foreground" Value="Black"></Setter>
<Setter Property="Padding" Value="5"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Height="{TemplateBinding Height}" Width="{TemplateBinding Width}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="ButtonHighlight" BorderThickness="2" BorderBrush="Transparent">
<Grid>
<Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" Stroke="Transparent"
StrokeThickness="20" Fill="{TemplateBinding Background}"
RadiusX="15" RadiusY="15" />
<ContentPresenter x:Name="Text" Content="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<ColorAnimation From="Transparent" To="Black" Storyboard.TargetName="Text" Storyboard.TargetProperty="(Button.Foreground).(SolidColorBrush.Color)" BeginTime="0" Duration="1"></ColorAnimation>
<ColorAnimation From="Transparent" To="LightSkyBlue" Storyboard.TargetName="Text" Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" BeginTime="0" Duration="1"></ColorAnimation>
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ColorAnimation From="Transparent" To="Black" Storyboard.TargetName="ButtonHighlight" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Duration="0:0:1"></ColorAnimation>
</Storyboard>
.
.
.
I snipped the extraneous code to keep the question short and to the point, but this all compile, just not getting the result desired. I could also use 2 rectangles (one smaller than the other), but would like to make it work with actual border.
Additionally what would be the difference between targeting:
<ColorAnimation From="Transparent" To="Black"
Storyboard.TargetName="ButtonHighlight"
Storyboard.TargetProperty="BorderBrush.(SolidColorBrush.Color)"
Duration="0:0:1"></ColorAnimation>
and
<ColorAnimation From="Transparent" To="Black"
Storyboard.TargetName="ButtonHighlight"
Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
Duration="0:0:1"></ColorAnimation>

The VisualState is called "MouseOver", not "PointerOver"

Related

Drag-and-Drop UWP vs Button Style

I have a question that is me to leave upset. I want to drag and drop an item in a listview and I can not do when I have a style applied to my item. Only I can do and is working perfectly when I have no style (MyButtonStyle) applied / or do not have this image in style. When I have style (MyButtonStyle), ItemDragStarting event is not called.
Another situation: I have tapped associated event, and when I apply this style crashes. I do not understand what the problem is, can someone help me?
Thank you:
Code MainPage:
<ListView x:Name="MyListView" ItemsSource="{x:Bind _ObservableCollection}" Style="{StaticResource MyListViewStyle}" SelectionMode="None" CanDragItems="True" DragItemsStarting="MyListView_OnDragItemsStarting">
<ListView.ItemTemplate>
<DataTemplate>
<Button Tapped="Item_Tapped" Style="{StaticResource MyButtonStyle}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
XAML Style code:
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="Background" Value="{StaticResource MyColor1}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="ButtonContent" Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ButtonContent" To="{StaticResource MyColor2}"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
Duration="00:00:00.1"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<PointerDownThemeAnimation TargetName="ButtonContent"/>
<ColorAnimation Storyboard.TargetName="ButtonContent" To="{StaticResource MyColor3}"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
Duration="00:00:00.1"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Image Width="200" Height="200">
<Image.Source>
<BitmapImage UriSource="{Binding MyImage, Mode=OneTime}" />
</Image.Source>
</Image>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The best solution for you would be to not use a Button at all. Use IsItemClickEnabled property and ItemClick event on the ListView instead, then put your image in the ItemContainerStyle. It will fix your drag and drop issues, focus problems and result in better performance.

Is it possible to style BorderThickness of RadioButton?

I'd like to change the BorderThickness of a RadioButton. Is this possible?
This is what I've got so far:
<Style TargetType="RadioButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderThickness" Storyboard.TargetName="Border">
<DiscreteObjectKeyFrame KeyTime="0" Value="6" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<!-- ... -->
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I read this post but somehow it's not working for me because:
The name "ThicknessAnimation" does not exist in the namespace "http://schemas.microsoft.com/client/2007"
Any ideas?
To answer your question: yes, it is possible to style the BorderThickness of the RadioButton control.
In what context do you want to change the BorderThickness?
In order to have one particular button show a thicker border just set the property accordingly:
<RadioButton x:Name="MyNiceFoobarButton" BorderThickness="6"/>
If you want all your RadioButtons to have a thicker border you have to use a Style:
<Style TargetType="RadioButton">
<Setter Property="BorderThickness" Value="6"/>
</Style>
[Edit]
And if you want your button to show a thicker border only while a paticular VisualState is active you have to overwrite the ControlTemplate and specify all VisualStates with their corresponding animations.

How to animate Rectangle Stroke Thickness in XAML?

I have been trying to change the stroke thickness of my button, but I seem to be missing something. The basic idea is I want the button to look zoomed in, as I shrink the transparent stroke (border) around the rectangle.
Here are the variations that I have used:
<DoubleAnimation To="10"
Storyboard.TargetName="innerRectangle"
Storyboard.TargetProperty="(Rectangle.StrokeProperty).StrokeThickness">
</DoubleAnimation>
I have also used the following line:
<DoubleAnimation To="10"
Storyboard.TargetName="innerRectangle"
Storyboard.TargetProperty="StrokeThickness">
</DoubleAnimation>
And:
<DoubleAnimation To="10"
Storyboard.TargetName="innerRectangle"
Storyboard.TargetProperty="(Rectangle.StrokeThickness)">
</DoubleAnimation>
None of the above works.
The entirety of the code is as follow:
<Style x:Key="SecondaryButton" TargetType="Button">
<!--<Setter Property="Background" Value="LightSkyBlue"></Setter>
<Setter Property="Foreground" Value="Black"></Setter>-->
<Setter Property="Padding" Value="5"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="Transparent" x:Name="RootGrid">
<Border x:Name="Outline" BorderBrush="Transparent" BorderThickness="2">
<Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" Stroke="Red"
StrokeThickness="15" Fill="LightSkyBlue"
RadiusX="15" RadiusY="15" />
</Border>
<ContentPresenter x:Name="Text" Content="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Black"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<!--<Storyboard>
<ColorAnimation To="Black" Storyboard.TargetName="Text" Storyboard.TargetProperty="(Button.Foreground).(SolidColorBrush.Color)"></ColorAnimation>
<ColorAnimation To="LightSkyBlue" Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"></ColorAnimation>
</Storyboard>-->
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<!--<ColorAnimation To="LightBlue" Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"></ColorAnimation>-->
<DoubleAnimation To="10"
Storyboard.TargetName="innerRectangle"
Storyboard.TargetProperty="(Rectangle.StrokeThickness)"
>
</DoubleAnimation>
<!--<ColorAnimation To="LightSkyBlue"
Storyboard.TargetName="innerRectangle"
Storyboard.TargetProperty="(Rectangle.Stroke).(SolidColorBrush.Color)">
</ColorAnimation>-->
<!--<ColorAnimation To="Red"
Storyboard.TargetName="Outline"
Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)">
</ColorAnimation>-->
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation To="10"
Storyboard.TargetName="innerRectangle"
Storyboard.TargetProperty="StrokeThickness">
</DoubleAnimation>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Make sure you Enable Dependent Animations.

Windows Phone 7 - Setting style for specific control within selected ListBoxItem

let's say i have something like this:
<Grid>
<ListBox x:Name="list"
ItemsSource="{Binding SomeCollection, Mode=TwoWay}"
SelectedItem="{Binding SomeItem, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="first" Text="{Binding SomeProperty}" />
<TextBlock x:Name="second" Text="{Binding OtherProperty}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Now, how do i alter some style property (f.ex. FontSize) of only the TextBlock called "second" when a ListBoxItem gets selected? If i'd like to set the FontSize for all ListBoxItem's contents, then i'd have no problem. That scenario is quite well documented here and elsewhere on the web.
I will not give you an exact solution, but a good point to start with: check out the file
C:\Program Files\Microsoft SDKs\Windows Phone\vX.Y\Design\System.Windows.xaml
you have to adjust X.Y to 7.0/7.1 along with your setup. There you will find exactly the same Control-Templates that are being used all the basic UI Controls of the WP7/Silverlight. Open it in VisualStudio-or-whateverelse and search for:
<Style TargetType="ListBoxItem">
(... and immediatelly following ~40 lines of xaml)
ah well, since I've opened that file, here's that
<!--x:Key="PhoneListBoxItem"-->
<Style TargetType="ListBoxItem">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Padding" Value="0" />
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="LayoutRoot" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver" />
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TransparentBrush}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetName="ContentContainer" Storyboard.TargetProperty="Opacity" Duration="0" To=".5" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected"/>
<VisualState x:Name="Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentContainer" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl x:Name="ContentContainer" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" Foreground="{TemplateBinding Foreground}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This is the complete style for your DEFAULT ListBoxItem - the thing you want to alter. Skim through the code and note the 'ContentPresenter' and preceding 'VisualStateGroup x:Name="SelectionStates"'.
ContentPresenter is the thing that will show your DataTemplate for the item.
VisualStates in that group define the changes from the normal state that should occur if a "selected state" is fired of on an list element.
Once the "selection state" diminishes, the element returns to the unselected state automatically and his visuals follow. Note also that the Unselected visual state does not enforce any changes - so it preserves your plain DataTemplate style.
The last thing to notice is that this is a style for ListBoxItem, and not for your data-item, nor your data-template. Your DataTemplate is never touched, it is directly displayed by the ContentPresenter. The ListBox wraps all your items in "ListBoxItem" instances, then displays those ListBoxItems and applies that style to them.
IMHO, this is the point you will have to work with.
You may want to copy&alter this style to your needs, and then set your ListBox.ItemContainerStyle to that new style. One of the ways is:
<YourPage.Resources>
<Style x:Key="mylistboxitemoverride" .....
........
</Style>
</YourPage.Resources>
...
...
<ListBox ......... ItemContainerStyle="{StaticResource mylistboxitemoverride}"
...
...
</ListBox>
Now, the trick is to modify the 'Selected' VisualState, and make it alter not the Foreground (doing that would restyle both your TextBoxes!), but some other property which will affect only one of your txbs. Unfortunatelly, that may be harder/uglier. I don't at that moment any idea how to make it "prettier" than hard-replacing the ContentPresenter with your DataTemplate and referencing your exact leaf-textbox in the VisualState like that:
<Style .... TargetType="ListBoxItem">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Padding" Value="0" />
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="LayoutRoot" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver" />
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TransparentBrush}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetName="SECOND" Storyboard.TargetProperty="Opacity" Duration="0" To=".5" /> <!-- #### RETARGETTED -->
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected"/>
<VisualState x:Name="Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SECOND" Storyboard.TargetProperty="Foreground"> <!-- #### RETARGETTED -->
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!-- #### INLINED YOUR DATATEMPLATE -->
<StackPanel Orientation="Vertical"
Margin="{TemplateBinding Padding}"
DataContext="{TemplateBinding Content}"> <!-- #### careful with the bindings. the DataCtx may be needed or is spurious. do check that! -->
<TextBlock Text="{Binding SomeProperty}" /> <!-- #### referenced from nowhere, so I removed the name -->
<TextBlock x:Name="SECOND" Text="{Binding OtherProperty}" />
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This should be almost what you want, or at least very close to it. I have not tested it, you may need to tinker with proper data-binding (I've included a DataContent=binding:Content, but that's a quick guess) and probably you will want to add your own animations. I think you have now tons of bits to experiment with. Have fun!
Set the Style on the TextBlock to a Style that does what you want.
<DataTemplate>
<TextBlock x:Name="first" Style="{StaticResource Header}" Text="{Binding SomeProperty}" />
<TextBlock x:Name="second" Style="{StaticResource Info}" Text="{Binding OtherProperty}" />
</DataTemplate>
one way to achieve this is, create an extended ListBox class with a SecondText dependency property in it. Then just use Blend to generate a normal ListBox style, change the targat type to my ExtendedListBox.
In this style, add another TextBlock control and set its Text TemplateBinding to the SecondText. You just need to alter this TextBlock's font size in the selected visual state.
Also, rather than extending the ListBox, you might be able to create an attached property SecondText and just TemplateBinding to it directly, but I haven't tested this method yet.
Hope this can get you started with. :)

Silverlight 4 - How can I change button background color when focused with an Implicit button style?

I'm having a great deal of difficulty trying to achieve something that should be trivial. I'm using an Implicit Button Style defined in a global XAML resource file. I just want to change the background color of the focused button to red with a ColorAnimation. I've tried a number of different combinations in Storyboard.TargetProperty and Storyboard.TargetName and nothing has worked. How can I achieve this?
Thanks in advance.
<Style TargetType="Button" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="grid" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Grid.RenderTransform>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused" >
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Button" From="Green" To="Red" Duration="00:00:01" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
...
Since I don't have the rest of your Style I made this with two Borders and a ContentPresenter. This animates the Background of the Button from Green to Red once focused.
<Style TargetType="Button" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="grid" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Grid.RenderTransform>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
From="Green"
To="Red"
Duration="0:0:1" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border BorderBrush="Transparent" BorderThickness="1" CornerRadius="4">
<Border x:Name="border" Background="White" BorderBrush="Black" BorderThickness="1" CornerRadius="4">
</Border>
</Border>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Width="Auto"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Some good answers here:
Style the MouseOver on a Silverlight/WPF button
http://forums.silverlight.net/forums/p/186402/427878.aspx