I am newbie in XAML area, I just want to learn about VSM. When I add something into the StoryBoard, there always alerted the same error. as below:
Cannot resolve TargetProperty Background.Color on specified object.
<phone:PhoneApplicationPage.Resources>
<ControlTemplate x:Key="ButtonControlTemplate1" TargetType="Button">
<Border
BorderThickness="{TemplateBinding BorderThickness}"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}"
Margin="{TemplateBinding Margin}"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
Name="btnBorder">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0"
To="Blue"
Storyboard.TargetName="btnBorder"
Storyboard.TargetProperty="Background.Color"
/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed"/>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" >
</ContentPresenter>
</Border>
</ControlTemplate>
</phone:PhoneApplicationPage.Resources>
<Button
x:Name="btnSubmit"
Grid.Row="3"
Grid.Column="0"
Grid.ColumnSpan="2"
Content="Login"
IsEnabled="False"
Click="btnSubmit_Click"
Margin="0"
BorderThickness="2"
BorderBrush="White"
Background="Aqua"
Padding="15"
Template="{StaticResource ButtonControlTemplate1}"
/>
why and how to fixed it, thanks!
Your visual state should be PointerOver rather than MouseOver.
Even so the ColorAnimation does nothing for me. This, however, does:
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="btnBorder"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="Blue" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
Note the target property is Background rather than Background.Color.
Related
I'd like to have the DatePicker prompt the user with a different message than "Select a date" for my DatePicker. Preferably I'd have a resx entry that would determine the value displayed, so is there a property of the DatePicker I can set to display a different opening message? I can deal with the resx portion of the problem myself, I just need help figuring out what property to set.
I've tried using datepicker.Text = "Enter a date", just as a test, but it does not display the string.
Here is the xaml markup for the DatePicker:
<DatePicker Height="28" HorizontalAlignment="Left" Margin="515,55.661,0,0" Name="dtpStartDate" VerticalAlignment="Top" Width="180" FontSize="16" Background="White" SelectedDateFormat="Short" TabIndex="20"/>
You could define an implicit DatePickerTextBox style where you hide the ContentControl named "PART_Watermark" and add a TextBlock with your custom text:
<DatePicker Height="28" HorizontalAlignment="Left" Margin="515,55.661,0,0" Name="dtpStartDate"
VerticalAlignment="Top" Width="180" FontSize="16" Background="White"
SelectedDateFormat="Short" TabIndex="20">
<DatePicker.Resources>
<Style TargetType="DatePickerTextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePickerTextBox}">
<Grid>
<Grid.Resources>
<SolidColorBrush x:Key="WatermarkBrush" Color="#FFAAAAAA"/>
</Grid.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
<VisualTransition GeneratedDuration="0:0:0.1" To="MouseOver"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0" To="#FF99C1E2" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="ContentElement"/>
<ColorAnimation Duration="0" To="#FF99C1E2" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="watermark_decorator"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="WatermarkStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Unwatermarked"/>
<VisualState x:Name="Watermarked">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentElement"/>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PART_Watermark"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisual"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="1" Opacity="1" Padding="{TemplateBinding Padding}">
<Grid x:Name="WatermarkContent" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Border x:Name="ContentElement" BorderBrush="#FFFFFFFF" BorderThickness="1"/>
<Border x:Name="watermark_decorator" BorderBrush="#FFFFFFFF" BorderThickness="1">
<Grid>
<ContentControl x:Name="PART_Watermark" Focusable="False" IsHitTestVisible="False" Opacity="0" Padding="2" Visibility="Collapsed"/>
<TextBlock Text="custom..." />
</Grid>
</Border>
<ScrollViewer x:Name="PART_ContentHost" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Border x:Name="FocusVisual" BorderBrush="#FF45D6FA" CornerRadius="1" IsHitTestVisible="False" Opacity="0"/>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DatePicker.Resources>
</DatePicker>
To display the value of a resource that is defined in a .resx file, you can set the Text property of the TextBlock using the x:Static markup extension like this where "AppResources" is the name of the .resx file and "HelloWorld" is the name of the string resource in the file:
<TextBlock Text="{x:Static local:AppResources.HelloWorld}" />
The only problem is when I choose a date, the watermark stays and is overlaid by the date. Is there any way to fix this?
Good point. You could apply a Style to the TextBlock and use a DataTrigger to bind to the SelectedDate property of the DatePicker:
<TextBlock Text="{x:Static local:AppResources.HelloWorld}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedDate, RelativeSource={RelativeSource AncestorType=DatePicker}}"
Value="{x:Null}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
I am currently trying to create a simple button in the shape of a circle that reacts int eh same way the default button does to a click (you can visually see a reaction when clicking on a default button, the color changes among other things).
I have made a circular button using the Ellipse attribute. This removed any reaction (in terms of visuals) the button had to a click.
In an attempt to bring it back I used the visual manager.
My issue is that I cannot combine the two successfully.
How should I go about doing this?
Is there perhaps a simpler way to make a round button that reacts to clicks?
Ideally I would like something that does this with code and avoid the use of Blend which I have seen mentioned in several places.
Below are the two code snippets in XAML.
Just a simple round button:
<Button Name="bottomCircle" Width="100" Height="100" HorizontalAlignment="Center" VerticalAlignment="Top" Grid.Row="2">
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Fill="Blue">
</Ellipse>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
A button with "animation":
<Button Content="Click Me" x:Name="ClickMe" Background="Blue" Grid.Row="2" Width="100" Height="100" >
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentContainer" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="Black" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PressedHighlightBackground" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentContainer" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="Green" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="Transparent" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="0" Background="{TemplateBinding Background}">
<Border x:Name="PressedHighlightBackground" Background="Transparent">
<ContentControl x:Name="ContentContainer" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Padding="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
</Border>
</Border>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
If you change the CornerRadius of your border elements to some large number, you'll get a circle:
<Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="100" Background="{TemplateBinding Background}">
<Border x:Name="PressedHighlightBackground" Background="Transparent"
CornerRadius="100">
<ContentControl x:Name="ContentContainer"
Foreground="{TemplateBinding Foreground}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Padding="{TemplateBinding Padding}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"/>
</Border>
</Border>
(I do believe you can get away with just a single Border element, though.)
Also, using Storyboard and ObjectAnimationUsingKeyFrames is cumbersome. You can use VisualState.Setters instead, which is easier to maintain.
To react to clicks and moseovers only within the circle, remove the outer Grid, which doesn't provide anything anyway. In addition, be advised that the visual state MouseOver works better if you rename it PointerOver.
This works the way you want:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button Content="Click Me" x:Name="ClickMe" Background="Blue" Grid.Row="2" Width="100" Height="100" Foreground="White">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border
x:Name="ButtonBackground"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="100" Background="{TemplateBinding Background}">
<Border
x:Name="PressedHighlightBackground"
Background="Transparent"
CornerRadius="100">
<ContentControl x:Name="ContentContainer"
Foreground="{TemplateBinding Foreground}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Padding="{TemplateBinding Padding}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"/>
</Border>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter
Target="ContentContainer.Foreground"
Value="Pink" />
<Setter
Target="PressedHighlightBackground.Background"
Value="Blue" />
<Setter
Target="ButtonBackground.BorderBrush"
Value="{StaticResource AppBarBackgroundThemeBrush}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter
Target="ContentContainer.Foreground"
Value="Black" />
<Setter
Target="PressedHighlightBackground.Background"
Value="{StaticResource AppBarBackgroundThemeBrush}" />
<Setter
Target="ButtonBackground.BorderBrush"
Value="{StaticResource AppBarBackgroundThemeBrush}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
I created a control template for a button which contains a grid and a content control. What I want to do is the following: when the button is pressed, the scale of the button should animate to 0.5 and when the button leaves the pressed state, the button's scale should animate back to 1.0.
In my current solution the animation to scale = 0.5 works nice, if the button is pressed. But as soon as i release the button, the animation doesn't scale slowly back to scale 1. Instead its immediate at scale 1.
My implementation looks like this:
<Style TargetType="Button" x:Name="MyButtonStyle">
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="{TemplateBinding Background}" x:Name="buttonLayoutRoot">
<Grid.RenderTransform>
<ScaleTransform ScaleX="1" ScaleY="1"/>
</Grid.RenderTransform>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition To="Pressed" GeneratedDuration="0:0:2.5">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="buttonLayoutRoot"
Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleX)"
To="0.5" Duration="0:0:2.5"/>
<DoubleAnimation
Storyboard.TargetName="buttonLayoutRoot"
Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleY)"
To="0.5" Duration="0:0:2.5"/>
</Storyboard>
</VisualTransition>
<VisualTransition To="Normal" GeneratedDuration="0:0:2.5">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="buttonLayoutRoot"
Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleX)"
To="1.0" Duration="0:0:2.5"/>
<DoubleAnimation
Storyboard.TargetName="buttonLayoutRoot"
Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleY)"
To="1.0" Duration="0:0:2.5"/>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver" />
<VisualState x:Name="Pressed"/>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl
x:Name="ButtonContent"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}">
</ContentControl>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I also tried to put the animations into the visual states "normal" and "pressed" without any transitions. But the outcome was the same. It just snaps back to scale = 1 when the button isn't pressed anymore.
I'm programming for windows phone 8.0 silverlight.
Hope you guys can help me.
Thanks, Kevin
The trick is, to define only the visual states, you are interested in. In this case, you are only interested in "pressed" and "normal", so only define those. Here is an example:
<Button.Template>
<ControlTemplate TargetType="Button">
<ContentPresenter x:Name="LayoutRoot" RenderTransformOrigin="0.5 0.5">
<ContentPresenter.RenderTransform>
<ScaleTransform/>
</ContentPresenter.RenderTransform>
<ContentPresenter.Foreground>
<SolidColorBrush Color="White"/>
</ContentPresenter.Foreground>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard Duration="0:0:0.5">
<DoubleAnimation Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(ContentPresenter.RenderTransform).(ScaleTransform.ScaleX)"
To="1" Duration="0:0:0.5"/>
<DoubleAnimation Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(ContentPresenter.RenderTransform).(ScaleTransform.ScaleY)"
To="1" Duration="0:0:0.5"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard Duration="0:0:0.5">
<DoubleAnimation Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(ContentPresenter.RenderTransform).(ScaleTransform.ScaleX)"
To="0.8" Duration="0:0:0.5"/>
<DoubleAnimation Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(ContentPresenter.RenderTransform).(ScaleTransform.ScaleY)"
To="0.8" Duration="0:0:0.5"/>
<ColorAnimation Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(ContentPresenter.Foreground).(SolidColorBrush.Color)"
To="Red" Duration="0"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</ContentPresenter>
</ControlTemplate>
</Button.Template>
As soon as the visual state manager changes state, the animations are reset, unless the new state is not declared in your template. F.e. if you define only the "pressed" state, the button will stay at scale 0.8. Only if you also declare "Normal", the animation is reset.
Ok, so looking at your stuff...you have another issue in how you're setting your RenderTransform explicit. Leave that thing open since we're interacting with it dynamically (look at the Grid.RenderTransform on my example). You also need to set a RenderTransformOrigin on your buttonLayoutRoot so it knows what you're snapping back too.
So while I don't have time at the moment to walk you through the entire explanation right at this moment since I've got my own work tasks to be doing, here's a generic button style you can use for reference I made awhile back that does what you want. Notice the differences. I pulled out most of my other custom crap in here so there shouldn't be any resource conflicts or anything, but you should probably notice the differences pretty quick.
<Style x:Key="StandardButtonStyle" TargetType="Button">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="Blue" />
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="Container"
RenderTransformOrigin="0.5,0.5" Cursor="{TemplateBinding Cursor}">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</Grid.RenderTransform>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition From="MouseOver"
GeneratedDuration="0:0:0.1"
To="Pressed">
<VisualTransition.GeneratedEasingFunction>
<ExponentialEase EasingMode="EaseIn" Exponent="-2" />
</VisualTransition.GeneratedEasingFunction>
</VisualTransition>
<VisualTransition From="Pressed"
GeneratedDuration="0:0:0.1"
To="MouseOver">
<VisualTransition.GeneratedEasingFunction>
<ExponentialEase EasingMode="EaseOut" Exponent="0" />
</VisualTransition.GeneratedEasingFunction>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Duration="00:00:00"
Storyboard.TargetName="MouseOverState" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Duration="00:00:00"
Storyboard.TargetName="PressedState" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Container" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0:0:0.01" Value="1.05" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Container" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0:0:0.01" Value="1.05" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Duration="00:00:00"
Storyboard.TargetName="DisabledState" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Duration="00:00:00"
Storyboard.TargetName="FocusedState" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="BaseBackground"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"/>
<Border x:Name="MouseOverState"
BorderThickness="{TemplateBinding BorderThickness}"
Visibility="Collapsed"/>
<Border x:Name="PressedState"
BorderThickness="{TemplateBinding BorderThickness}"
Visibility="Collapsed"/>
<Border x:Name="FocusedState"
Background="{TemplateBinding Background}"
Visibility="Collapsed"/>
<ContentControl x:Name="contentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontWeight="{TemplateBinding FontWeight}"
Foreground="{TemplateBinding Foreground}"
IsTabStop="False"/>
<Border x:Name="DisabledState"
Background="White"
Visibility="Collapsed"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Hope this helps, cheers! :)
I have a ListView where I am changing the foreground color of selected item:
<ListView ItemsSource="{Binding Levels}"
x:Name="LvLevels" SelectionChanged="LvLevels_SelectionChanged">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected">
<Storyboard>
<ColorAnimation Duration="0" Storyboard.TargetName="myback" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="Red"/>
</Storyboard>
</VisualState>
<VisualState x:Name="SelectedUnfocused">
<Storyboard>
<ColorAnimation Duration="0" Storyboard.TargetName="myback" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="#16C8E0"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="myback" Background="Transparent">
<ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="../Assets/icons/uno.png"
Margin="10 0 0 0"/>
<TextBlock x:Name="tblock" Text="{Binding}" Grid.Column="1" FontSize="30" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
How can I change the foreground color of TextBlock of selected item in my case ?
I have tried to use:
<ColorAnimation Duration="0" Storyboard.TargetName="tblock"
Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)"
To="White"/>
but got the exception:
Exception = {"No installed components were detected.\r\n\r\nCannot resolve TargetName tblock."}
You are getting the exception because style for ListViewItem cannot know about the structure/elements in its item template.
The easiest way is to redefine the ListViewItem container style. You need to specify also VisualState for "Selected" state within "SelectionStates". There you can animate foreground property of some element (ContentPresenter does not have it, so I used ContentControl).
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Selected">
<Storyboard>
<ColorAnimation Duration="0" Storyboard.TargetName="contentControl" Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)" To="GreenYellow"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unselected">
<Storyboard>
<ColorAnimation Duration="0" Storyboard.TargetName="myback" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="Red"/>
</Storyboard>
</VisualState>
<VisualState x:Name="SelectedUnfocused">
<Storyboard>
<ColorAnimation Duration="0" Storyboard.TargetName="myback" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="#16C8E0"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="myback" Background="Transparent">
<ContentControl x:Name="contentControl" Foreground="{TemplateBinding Foreground}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
I have a WinRT app control template for a textbox. I want the background to go gray when the control is in focus. The code below does this, but when the control loses focus the gray background remains. How do I make it so the background returns to normal when the control loses focus?
<ControlTemplate x:Key="GreyFocusTextBox" TargetType="TextBox">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver" />
<VisualState x:Name="Pressed" />
<VisualState x:Name="Disabled" />
</VisualStateGroup>
<VisualStateGroup x:Name="FocusedStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
<VisualState x:Name="PointerFocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="BackgroundElement" Background="Gray" Grid.ColumnSpan="2" Margin="{TemplateBinding BorderThickness}" Opacity="0" />
<Border x:Name="BorderElement" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Grid.ColumnSpan="2"/>
<ScrollViewer x:Name="ContentElement" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsTabStop="False" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="Disabled"/>
</Grid>
</ControlTemplate>
It seems like textbox doesn't go to unfocused state so I just rename Unfocused to Normal & removed the Storyboard and it worked. Below code worked for me.
<ControlTemplate x:Key="GreyFocusTextBox" TargetType="TextBox">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="FocusedStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement" />
</Storyboard>
</VisualState>
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerFocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="BackgroundElement" Background="Gray" Grid.ColumnSpan="2" Margin="{TemplateBinding BorderThickness}" Opacity="0" />
<Border x:Name="BorderElement" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Grid.ColumnSpan="2"/>
<ScrollViewer x:Name="ContentElement" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsTabStop="False" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="Disabled"/>
</Grid>
</ControlTemplate>
<VisualStateGroup x:Name="FocusedStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement" />
</Storyboard>
</VisualState>
<VisualState x:Name="PointerFocused" />
</VisualStateGroup>
you should change state Unfocused