How to change the background image of button on runtime? - c#

I m stuck with a problem. I want to change the background image of button on runtime. I got the solution for changing the color but i want to change the image.
The code is as follows
public void buttonCase(object sender, RoutedEventArgs e)
{
Uri uri = null;
var image = new ImageBrush();
if (((App)App.Current).appControler.m_Mode == Controller.textMode.Letters)
{
((App)App.Current).appControler.buttonCase(sender, e);
switch (((App)App.Current).appControler.m_case)
{
case Controller.caseMode.Upper:
b0.FontSize = b1.FontSize = b2.FontSize = b3.FontSize = b4.FontSize = b5.FontSize = b6.FontSize = b7.FontSize
= b8.FontSize = b9.FontSize = bCornerLower.FontSize = 30.0;
uri = new Uri(#"/SourceCode;component/Images/Lower_Case_p.png", UriKind.Relative);
image.ImageSource = new BitmapImage(uri);
btnCase.Background = image;
break;
case Controller.caseMode.Lower:
b0.FontSize = b1.FontSize = b2.FontSize = b3.FontSize = b4.FontSize = b5.FontSize = b6.FontSize = b7.FontSize
= b8.FontSize = b9.FontSize = bCornerLower.FontSize = 40.0;
uri = new Uri(#"/SourceCode;component/Images/Case_p.png", UriKind.Relative);
image.ImageSource = new BitmapImage(uri);
btnCase.Background = image;
break;
}
}
}

Something like this?
var brush = new ImageBrush();
brush.ImageSource = new BitmapImage(new Uri(#"Images/myImage.png", UriKind.Relative));
myButton.Background = brush;
[Edit] I made a test application with two images. I toggle the image on button click and it works.
private bool flag;
private void button1_Click(object sender, RoutedEventArgs e)
{
flag = !flag;
var uriString = flag ? #"Images/logo.png" : #"Images/icon.png";
myButton.Background = new ImageBrush
{ ImageSource = new BitmapImage(new Uri(uriString, UriKind.Relative)) };
}

private void button_Click(object sender, EventArgs e)
{
button.Image=System.Drawing.Image.FromFile("image.png");
}
try this..

Utilize VisualStates for this kind of UI state switching.
Your code behind would look like this:
public void buttonCase(object sender, RoutedEventArgs e)
{
if (((App)App.Current).appControler.m_Mode == Controller.textMode.Letters)
{
((App)App.Current).appControler.buttonCase(sender, e);
switch (((App)App.Current).appControler.m_case)
{
case Controller.caseMode.Upper:
VisualStateManager.GoToState( this, "UpperCase", true );
break;
case Controller.caseMode.Lower:
VisualStateManager.GoToState( this, "LowerCase", true );
break;
}
}
}
And your xaml would look like this:
<UserControl
x:Class="SilverlightApplication2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<UserControl.Resources>
<ControlTemplate x:Key="MySpecialToggleButton" TargetType="ToggleButton">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="LowerCaseIcon">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="UpperCaseIcon">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Image x:Name="UpperCaseIcon" Source="/SilverlightApplication2;component/Images/Lower_Case_p.png" Visibility="Visible"/>
<Image x:Name="LowerCaseIcon" Source="/SilverlightApplication2;component/Images/Case_p.png" Visibility="Collapsed"/>
</Grid>
</ControlTemplate>
</UserControl.Resources>
<StackPanel>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="LetterCaseStates">
<VisualState x:Name="UpperCase"/>
<VisualState x:Name="LowerCase">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="FontSize" Storyboard.TargetName="bCornerLower">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<system:Double>40</system:Double>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ToggleButton x:Name="btnCase" Click="buttonCase" Template="{StaticResource MySpecialToggleButton}"/>
<Button x:Name="bCornerLower" FontSize="30"/><!-- this one is the styling master, all other buttons follow its styling -->
<Button x:Name="b0" FontSize="{Binding ElementName=bCornerLower, Path=FontSize}"/>
<Button x:Name="b1" FontSize="{Binding ElementName=bCornerLower, Path=FontSize}"/>
<Button x:Name="b2" FontSize="{Binding ElementName=bCornerLower, Path=FontSize}"/>
<Button x:Name="b3" FontSize="{Binding ElementName=bCornerLower, Path=FontSize}"/>
<Button x:Name="b4" FontSize="{Binding ElementName=bCornerLower, Path=FontSize}"/>
<Button x:Name="b5" FontSize="{Binding ElementName=bCornerLower, Path=FontSize}"/>
<Button x:Name="b6" FontSize="{Binding ElementName=bCornerLower, Path=FontSize}"/>
<Button x:Name="b7" FontSize="{Binding ElementName=bCornerLower, Path=FontSize}"/>
<Button x:Name="b8" FontSize="{Binding ElementName=bCornerLower, Path=FontSize}"/>
<Button x:Name="b9" FontSize="{Binding ElementName=bCornerLower, Path=FontSize}"/>
</StackPanel>
I wrote the code as an answer to a similar question here:toggle button with different images
I know that defining VisualStates can look quite cumbersome, but in the end you can keep your code behind quite clean from switching visual appearance of all the ui bits and pieces.

Related

How to convert VisualState xaml to c#

Visual States in XAML
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SectionHeader">
<VisualState x:Name="SectionHeaderNormal">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1200"/>
</VisualState.StateTriggers>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="txtUser" Storyboard.TargetProperty="Style">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource usernameStyle}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="txtName" Storyboard.TargetProperty="Style">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource nameStyle}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
I need to create this XAML code programmatically via C# code.
Current code
var vsg = new VisualStateGroup();
var vs = new VisualState();
vs.StateTriggers.Add(new AdaptiveTrigger
{
MinWindowWidth = 1200.0
});
How do I create storyboards and add these properties?
If you want to use the VisualState in code behind, you should be able to add Setter to SetterBaseCollection of the VisualState. Also we should be able to add the VisualState to the VisualStateGroup. Then we can add the VisualStateGroup to our control.
To get the Style in code behind, we should be able to use the FrameworkElement.Resources.
For example:
<Page.Resources>
<Style x:Key="usernameStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="Red" />
</Style>
</Page.Resources>
<Grid Name="MyGrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock Name="txtUser" Text="555555" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</Grid>
The code behind:
public MainPage()
{
this.InitializeComponent();
var vsg = new VisualStateGroup();
var vs = new VisualState();
Style appButtonStyle = (Style)this.Resources["usernameStyle"];
vs.StateTriggers.Add(new AdaptiveTrigger
{
MinWindowWidth = 1080
});
vs.Setters.Add(new Setter
{
Target = new TargetPropertyPath
{
Path = new PropertyPath("(TextBlock.Style)"),
Target = txtUser
},
Value = appButtonStyle
});
vsg.States.Add(vs);
VisualStateManager.GetVisualStateGroups(MyGrid).Add(vsg);
}

How to display validation errors on silverlight TextBlock

I have a tree which represents XML document. And I show XML validations errors using a bound class which implements INotifyDataErrorInfo.
It works all fine on editable controls like text box or combo.
But some nodes are just text blocks. And they have errors too.
How do I go about it?
I recommend you wrap your TextBlock in a ValidationErrorBorder:
<ValidationErrorBorder DataContextValidationTargetPath="MyTextProperty">
<TextBlock Text="{Binding Path=MyTextProperty}"/>
</ValidationErrorBorder>
ValidationErrorBorder control code:
/*
* Use in conjuction with other Controls that do not have the appropriate
* visualStates to indicate ValidationErrors.
* Either set DataContextValidationTargetPath to have this
* ValidationErrorBorder show validation errors that occur at the targeted
* property of the DataContext
* or bind ValidationTarget to any target you wish to have this
* ValidationErrorBorder show validation errors occuring for the bound target.
*/
[TemplateVisualState(GroupName="ValidationStates", Name = "Valid")]
[TemplateVisualState(GroupName="ValidationStates", Name = "InvalidUnfocused")]
[TemplateVisualState(GroupName="ValidationStates", Name = "InvalidFocused")]
public class ValidationErrorBorder : ContentControl
{
public object ValidationTarget
{
get { return GetValue( ValidationTargetProperty ); }
set { SetValue( ValidationTargetProperty, value ); }
}
public static readonly DependencyProperty ValidationTargetProperty =
DependencyProperty.Register( "ValidationTarget", typeof( object ),
typeof( ValidationErrorBorder ), new PropertyMetadata( null ) );
public string DataContextValidationTargetPath
{
get
{
return (string) GetValue( DataContextValidationTargetPathProperty );
}
set { SetValue( DataContextValidationTargetPathProperty, value ); }
}
public static readonly DependencyProperty
DataContextValidationTargetPathProperty =
DependencyProperty.Register( "DataContextValidationTargetPath",
typeof( string ), typeof( ValidationErrorBorder ),
new PropertyMetadata( null, HandlePathChanged ) );
private static void HandlePathChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
((ValidationErrorBorder) d).HandlePathChanged();
}
private void HandlePathChanged()
{
if (DataContextValidationTargetPath != null)
SetBinding(ValidationTargetProperty,
new Binding(DataContextValidationTargetPath));
else
ClearValue( ValidationTargetProperty );
}
public ValidationErrorBorder()
{
DefaultStyleKey = typeof( ValidationErrorBorder );
}
}
and the control template:
<Style TargetType="controls:ValidationErrorBorder">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:ValidationErrorBorder">
<Grid x:Name="RootElement" Background="{x:Null}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ValidationStates">
<VisualState x:Name="Valid"/>
<VisualState x:Name="InvalidUnfocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ValidationErrorElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="InvalidFocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ValidationErrorElement">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsOpen" Storyboard.TargetName="validationTooltip">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<system:Boolean>True</system:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" />
<Border x:Name="ValidationErrorElement" BorderBrush="#FFDB000C" BorderThickness="1" CornerRadius="1" Visibility="Collapsed">
<ToolTipService.ToolTip>
<ToolTip x:Name="validationTooltip" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Placement="Right" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" Template="{StaticResource ValidationToolTipTemplate}">
<ToolTip.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="validationTooltip">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<system:Boolean>True</system:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ToolTip.Triggers>
</ToolTip>
</ToolTipService.ToolTip>
<Grid Background="Transparent" HorizontalAlignment="Right" Height="12" Margin="1,-4,-4,0" VerticalAlignment="Top" Width="12">
<Path Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" Fill="#FFDC000C" Margin="1,3,0,0"/>
<Path Data="M 0,0 L2,0 L 8,6 L8,8" Fill="#ffffff" Margin="1,3,0,0"/>
</Grid>
</Border>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and the validationTooltipTemplate:
<ControlTemplate x:Key="ValidationToolTipTemplate">
<Grid x:Name="Root" Margin="5,0" Opacity="0" RenderTransformOrigin="0,0">
<Grid.RenderTransform>
<TranslateTransform x:Name="xform" X="-25"/>
</Grid.RenderTransform>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="OpenStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
<VisualTransition GeneratedDuration="0:0:0.2" To="Open">
<Storyboard>
<DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetProperty="X" Storyboard.TargetName="xform">
<DoubleAnimation.EasingFunction>
<BackEase Amplitude=".3" EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Duration="0:0:0.2" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Closed">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Open">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="X" Storyboard.TargetName="xform"/>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border Background="#052A2E31" CornerRadius="5" Margin="4,4,-4,-4"/>
<Border Background="#152A2E31" CornerRadius="4" Margin="3,3,-3,-3"/>
<Border Background="#252A2E31" CornerRadius="3" Margin="2,2,-2,-2"/>
<Border Background="#352A2E31" CornerRadius="2" Margin="1,1,-1,-1"/>
<Border Background="#FFDC000C" CornerRadius="2"/>
<Border CornerRadius="2">
<TextBlock Foreground="White" MaxWidth="250" Margin="8,4,8,4" TextWrapping="Wrap" Text="{Binding (Validation.Errors)[0].ErrorContent}" UseLayoutRounding="false"/>
</Border>
</Grid>
</ControlTemplate>
It is not really supported in Silverlight by default. One way that I have found to work well in the past is to make a control that inherits from Textblock. You can then handle the IDatanotify interface and exceptions and turn the textblock different colors based off of those.

Animate custom button using ViewStateManager

I'm working on a custom button for my project.
I'm not using a default Button but just a ContentControl with a ControlTemplate assigned to it.
For the beginning just a simple template:
<ControlTemplate x:Key="MySampleTemplate">
<Image x:Name="img" Source="/AppName;component/Res/Img/normalstate.png" />
</ControlTemplate>
Now I would like to animate the image by using VisualStateManager.
First I created a "Hover" and a "Normal" state:
<ControlTemplate x:Key="MySampleTemplate">
<Image x:Name="img" Source="/AppName;component/Res/Img/normalstate.png">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal" />
<VisualState Name="Hover">
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="0"
Storyboard.TargetName="img" Storyboard.TargetProperty="Source">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="/AppName;component/Res/Img/hoverstate.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Image>
</ControlTemplate>
In Code behind:
btnSampleButton.MouseEnter += (s,e) => VisualStateManager.GoToState(btnSampleButton, "Hover", false);
btnSampleButton.MouseLeave += (s,e) => VisualStateManager.GoToState(btnSampleButton, "Normal", false);
Everything works just fine. If I hover over the button hoverstate.png is shown and if I don't hover over normalstate.png is shown.
Now I would like to animate LeftMouseButtonDown and LeftMouseButtonUp to achieve a pressing animation if the user click on the button.
I created a VisualState called "Pressed" and just set it up like "Hover" (just replaced hoverstate.png with pressedstate.png).
In the code behind I did this:
btnSampleButton.MouseLeftButtonDown += (s,e) => VisualStateManager.GoToState(btnSampleButton, "Pressed", false);
btnSampleButton.MouseLeftButtonUp += (s,e) => VisualStateManager.GoToState(btnSampleButton, btnSampleButton.IsMouseOver ? "Hover" : "Normal", false);
However it does not work. MouseEnter and MouseLeave work fine but I can't see any changes to the button if I press/release my left mouse button.
Do you have any advice to get it work?
Edit:
Control:
<ContentControl x:Name="btnSampleButton" Template="{StaticResource SamplButtonTemplate}" />
ControlTemplate:
<ControlTemplate x:Key="SamplButtonTemplate">
<Image x:Name="Image" Source="/AppName;component/Res/Img/normalstate.png">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal" />
<VisualState Name="Hover">
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="0"
Storyboard.TargetName="Image" Storyboard.TargetProperty="Source">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="/AppName;component/Res/Img/hoverstate.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="0" FillBehavior="Stop"
Storyboard.TargetName="Image" Storyboard.TargetProperty="Source">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="/AppName;component/Res/Img/pressedstate.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Image>
</ControlTemplate>
Code behind:
btnSampleButton.MouseEnter += (s, e) => VisualStateManager.GoToState(btnSampleButton, "Hover", false);
btnSampleButton.MouseLeave += (s, e) => VisualStateManager.GoToState(btnSampleButton, "Normal", false);
btnSampleButton.PreviewMouseLeftButtonDown +=
(s, e) => VisualStateManager.GoToState(btnSampleButton, "Pressed", false);
btnSampleButton.PreviewMouseLeftButtonUp +=
(s, e) => VisualStateManager.GoToState(btnSampleButton, btnSampleButton.IsMouseOver ? "Hover" : "Normal", false);
MouseLeftButtonDown and MouseLeftButtonUp gets swallowed by Click event of Button that's why these events are never raised for button and no change in VisualState.
Instead hook corresponding Preview events i.e. PreviewMouseLeftButtonDown and PreviewMouseLeftButtonUp :
btnSampleButton.PreviewMouseLeftButtonDown += (s,e) =>
VisualStateManager.GoToState(btnSampleButton, "Pressed", false);
btnSampleButton.PreviewMouseLeftButtonUp += (s,e) =>
VisualStateManager.GoToState(btnSampleButton, btnSampleButton.IsMouseOver ?
"Hover" : "Normal", false);
Remove FillBehavior="Stop" from second StoryBoard and your code works fine.
<VisualState Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="0"
FillBehavior="Stop" <-- Remove this
Storyboard.TargetName="Image"
Storyboard.TargetProperty="Source">

text highlighting animation in windows 8 apps

i want to create an animation where each word of a line changes its foreground color from black to white after some intervals.
initially all the words are set to black.
i have used this code:
DispatcherTimer text1timer = new DispatcherTimer();
text1timer.Interval = TimeSpan.FromMilliseconds(440);
text1timer.Tick += text1timer_Tick;
text1timer.Start();
void text1timer_Tick(object sender, object e)
{
text1timer.Tick -= text1timer_Tick;
txt1.Foreground = new SolidColorBrush(Colors.White);
text1timer.Stop();
text1timer.Tick += text2timer_Tick;
text1timer.Start();
}
private void text2timer_Tick(object sender, object e)
{
text1timer.Tick -= text2timer_Tick;
txt2.Foreground = new SolidColorBrush(Colors.White);
text1timer.Stop();
text1timer.Tick += text3timer_Tick;
text1timer.Start();
}
private void text3timer_Tick(object sender, object e)
{
text1timer.Tick -= text3timer_Tick;
txt3.Foreground = new SolidColorBrush(Colors.White);
text1timer.Stop();
text1timer.Tick += text4timer_Tick;
text1timer.Start();
}
and so on but i have more than 100 words and i will have to make more than 100 events of the timer.is there any other solution?
You can use StoryBoard for the desired functionality.Check the following codes.
<Page.Resources>
<Storyboard x:Name="TextForegroundSb" RepeatBehavior="Forever">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Tag)" Storyboard.TargetName="textBlock">
<DiscreteObjectKeyFrame KeyTime="0:0:0.0" Value="Red"/>
<DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="Green"/>
<DiscreteObjectKeyFrame KeyTime="0:0:0.4" Value="Blue"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Page.Resources>
Here is the Textblock
<TextBlock x:Name="textBlock" TextWrapping="Wrap" Text="TextBlock" FontSize="48" Tag="Red" FontWeight="Bold" Foreground="{Binding Tag, RelativeSource={RelativeSource Mode=Self}}" FontFamily="Global User Interface" />
Also you can modify the time by changing DiscreteObjectKeyFrame KeyTime property.
For playing the storyboard on a button click use this code.
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity" <br/>
xmlns:Core="using:Microsoft.Xaml.Interactions.Core" <br/>
xmlns:Media="using:Microsoft.Xaml.Interactions.Media" <br/>
<Button Content="Start sb" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="915,285,0,0" Height="119" Width="276">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Click">
<Media:ControlStoryboardAction Storyboard="{StaticResource TextForegroundSb}"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
Hope this helps.
Thanks..
Use storyboard! there are instructions online and on MSDN.

Using VisualStateManager to start and stop Storyboards

I have an animation that animates a Canvas by turning it 360 degrees indefinitely (it basically spins). What I want is for this animation to start when the control is shown and then stop when the control is hidden. I figured I could tie this in, somehow, to the VisualStateManager. I have seen an example of fading in and out controls here which could work but I just dont know how to use VSM to start and stop the storyboard
<Canvas.Resources>
<Storyboard x:Name="spinnerBoard">
<DoubleAnimation
Storyboard.TargetName="SpinnerRotate"
Storyboard.TargetProperty="Angle"
From="0" To="360" Duration="0:0:01.3"
RepeatBehavior="Forever" />
</Storyboard>
</Canvas.Resources>
<Canvas.RenderTransform>
<RotateTransform x:Name="SpinnerRotate" Angle="0" />
</Canvas.RenderTransform>
Example VSM
<VisualState x:Name="Show">
<Storyboard>
<!-- Start the story board here -->
</Storyboard>
</VisualState>
<VisualState x:Name="Hide">
<Storyboard>
<!-- Stop the story board here -->
</Storyboard>
</VisualState>
A global answer of your different questions :
ExtendedVisualStateManager.GoToElementState returns false in Silverlight
Default binding to UserControl for custom DP
You can do something like this :
Use a template control that extend ContentControl to play with
IsEnabled of content (prevent action during waiting) ;
Create a DP IsWaiting that switch your control visual state ;
Create the two states in XAML : Use DoubleAnimation with RepeatBehavior="Forever"
After you can add a overlay and a Waiting message dependency property like the busy indicator control...
I use a picture for the Waiting visual part but you can use a canvas, grid etc...
C#
[TemplateVisualState(GroupName = "WaitGroup", Name = WaitSpinner.IsWaitingStateName)]
[TemplateVisualState(GroupName = "WaitGroup", Name = WaitSpinner.NotWaitingStateName)]
public class WaitSpinner : ContentControl
{
#region States names
internal const String IsWaitingStateName = "IsWaitingState";
internal const String NotWaitingStateName = "NotWaitingState";
#endregion States names
public bool IsWaiting
{
get { return (bool)GetValue(IsWaitingProperty); }
set { SetValue(IsWaitingProperty, value); }
}
public static readonly DependencyProperty IsWaitingProperty =
DependencyProperty.Register("IsWaiting", typeof(bool), typeof(WaitSpinner), new PropertyMetadata(false, OnIsWaitingPropertyChanged));
private static void OnIsWaitingPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
WaitSpinner waitSpinner = (WaitSpinner)sender;
waitSpinner.ChangeVisualState(true);
}
public WaitSpinner()
{
DefaultStyleKey = typeof(WaitSpinner);
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
ChangeVisualState(false);
}
protected virtual void ChangeVisualState(bool useTransitions)
{
VisualStateManager.GoToState(this, IsWaiting ? IsWaitingStateName : NotWaitingStateName, useTransitions);
}
}
Xaml :
<VisualStateGroup x:Name="WaitGroup">
<VisualState x:Name="NotWaitingState" >
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Control.IsEnabled)" Storyboard.TargetName="content">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<System:Boolean>True</System:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="IsWaitingState">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="WaitPart">
<DiscreteObjectKeyFrame KeyTime="0:0:0.200" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)" Storyboard.TargetName="WaitPart" To="360" RepeatBehavior="Forever" Duration="0:0:1" />
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Control.IsEnabled)" Storyboard.TargetName="content">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<System:Boolean>False</System:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<!-- ............. -->
<ContentControl
IsTabStop="False"
x:Name="content"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Foreground="{TemplateBinding Foreground}"
ScrollViewer.HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
ScrollViewer.VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"/>
<Image Source="CirclePicture.png"
x:Name="WaitPart"
RenderTransformOrigin="0.5,0.5"
Width="16"
Height="16"
Visibility="Collapsed"
IsHitTestVisible="False">
<Image.RenderTransform>
<RotateTransform />
</Image.RenderTransform>
</Image>

Categories