WPF: How to animate color change? - wpf

I have a grid, a window root element. I want to apply an animation which would change it's background color from white to green in 5 seconds. Here's what I did:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ColorAnimation animation;
animation = new ColorAnimation();
animation.From = Colors.White;
animation.To = Colors.Green;
animation.Duration = new Duration(TimeSpan.FromSeconds(5));
rootElement.BeginAnimation(Grid.BackgroundProperty, animation);
}
The code doesn't work. Nothing is changing. Where am I making a mistake? Thanks.

Solved!
private void Window_Loaded(object sender, RoutedEventArgs e)
{
SolidColorBrush rootElementBrush;
ColorAnimation animation;
rootElementBrush = this.FindResource("RootElementBrush") as SolidColorBrush;
// Animate the brush
animation = new ColorAnimation();
animation.To = Colors.Green;
animation.Duration = new Duration(TimeSpan.FromSeconds(5));
rootElementBrush.BeginAnimation(SolidColorBrush.ColorProperty, animation);
}
Here's an explanation:
My initial mistake was that I wanted to change the Grid.BackgroundProperty by assigning colors to it, but it accepts brushes instead... apples and oranges! So, I created a SolidColorBrush static resource and named it rootElementBrush. In XAML, I set Grid rootElement's background property to that static resource. And finally, I modified the animation, so now it changes the color for that SolidColorBrush. Easy!

Give this a try:
<ColorAnimation
Storyboard.TargetName="PlayButtonArrow"
Storyboard.TargetProperty="Fill.Color"
From="White"
To="Green"
Duration="0:0:5.0"
AutoReverse="False"/>

You do not need to set the StaticResource, just use the Storyboard.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// Animate the brush
ColorAnimation animation = new ColorAnimation();
animation.To = Colors.Green;
animation.Duration = new Duration(TimeSpan.FromSeconds(5));
Storyboard.SetTargetProperty(animation, new PropertyPath("(Grid.Background).(SolidColorBrush.Color)", null));
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(animation);
storyboard.Begin(rootElement);
}

Related

Update ImageBrush from ResourceDictionary at runtime

In my WP7 application, all the pages use an ImageBrush as the background that I have defined in a ResourceDictionay. This ResourceDictionary is merged globally through the App.xaml. The ImageBrush in the ResourceDictionary is defined like this:
<ImageBrush x:Key="PhonePageBackground" ImageSource="/Background1.jpg"/>
Im trying to update the ImageSource of the ImageBrush at runtime, but its not working.
Making some tests, where I have a page with a button on it to change the background, I realized that the code below works fine:
ImageBrush image;
public MainPage()
{
InitializeComponent();
image = new ImageBrush { ImageSource = new BitmapImage(new Uri("/Background1.jpg", UriKind.Relative)) };
LayoutRoot.Background = image;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
image.ImageSource = new BitmapImage(new Uri("/Background2.jpg", UriKind.Relative));
}
But the code below, where I use the ImageBrush from the dictionary, does not work. The background of the page becomes transparent, as if the image could not be found:
ImageBrush image;
public MainPage()
{
InitializeComponent();
image = (ImageBrush)Application.Current.Resources["PhonePageBackground"];
LayoutRoot.Background = image;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
image.ImageSource = new BitmapImage(new Uri("/Background2.jpg", UriKind.Relative));
}
Both images (Background1.jpg and Background2.jpg) build action are set as Content. I've tested with Resource set, but without success.
Any knowledge of why this behavior?
This works for me.
ImageBrush image;
public MainPage()
{
InitializeComponent();
image = (ImageBrush)Application.Current.Resources["PhonePageBackground"];
LayoutRoot.Background = image;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
image = new ImageBrush { ImageSource = new BitmapImage(new Uri("/Background2.jpg", UriKind.Relative)) };
LayoutRoot.Background = image;
}

How to set a background image for a window by clicking on the cntl button using wpf?

I want to set an image as background by clicking the ctrl button?
Any one have ideas? please revert me ASAP.
Thanks in advance.
On button click event apply the following code
ImageBrush myBrush = new ImageBrush();
myBrush.ImageSource =
new BitmapImage(new Uri(#"Image Path"));
this.Background = myBrush;
You can replace the this with your control name
You can try the following code:
private void button1_Click(object sender, RoutedEventArgs e)
{
BitmapImage imageSource = new BitmapImage(new Uri(#"Path/to/image.jpg"));
ImageBrush brush = new ImageBrush();
brush.ImageSource = imageSource;
grid.Background = brush;
}

Infinite Loop when binding slider in MVVM

I have a video progress slider in XAML thus:
<Slider Minimum="0" Value="{Binding Position,Mode=OneWay}" Maximum="{Binding Duration}" IsMoveToPointEnabled="True"/>
And code in my viewmodel to update Position on Clock.CurrentTimeInvalidated(), which keeps the slider tracking current progress:
private void Play()
{
Uri next = _carousel.Dequeue();
_timeline = new MediaTimeline(next);
_timeline.RepeatBehavior = RepeatBehavior.Forever;
_clock = _timeline.CreateClock();
MyMediaElement.Clock = _clock;
_clock.CurrentTimeInvalidated += new EventHandler(UpdatePosition);
_clock.Controller.Begin();
}
public void UpdatePosition(object sender, EventArgs e)
{
Position = MyMediaElement.Position.TotalMilliseconds;
}
This works fine, except when I implement ValueChanged to set Clock.Controller.Seek():
private void seekSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
DisplayViewModel vm = (DisplayViewModel)this.DataContext;
TimeSpan ts = new TimeSpan(0, 0, 0, 0, (int)seekSlider.Value);
vm.MyMediaElement.Clock.Controller.Seek(ts, TimeSeekOrigin.BeginTime);
}
(In my user control's codebehind until I figure out event-to-command routing)
At this point I get an infinite loop. Previously in non-MVVM I simply disabled the Slider.ValueChanged() event handler during UpdatePosition:
public void UpdatePosition(object sender, EventArgs e)
{
seekSlider.ValueChanged -= new EventHandler(seekSlider_ValueChanged);
Position = MyMediaElement.Position.TotalMilliseconds;
seekSlider.ValueChanged += new EventHandler(seekSlider_ValueChanged);
}
...but now I'm in a viewmodel I no longer have access to my slider control.
Is there another way to disable the infinite loop/event handler?
Consider moving the logic from seekSlider_ValueChanged to the setter of the Position property in your ViewModel.

StackPanel position

How can I find the position of a StackPanel after it has been animated?
I have a button which slides the stackpanel to the left. But if I want it to slide to the left again, the animation does not work.
Nevermind. I found out how to do this...
private Storyboard SlideEffect(UIElement controlToAnimate, double positionToMove)
{
//Get position of stackpanel
GeneralTransform gt = controlToAnimate.TransformToVisual(gridWrapper);
Point p = gt.Transform(new Point(0, 0));
//add new storyboard and animation
Storyboard sb = new Storyboard();
DoubleAnimation da = new DoubleAnimation();
da.To = p.X + positionToMove;
Storyboard.SetTarget(da, controlToAnimate);
Storyboard.SetTargetProperty(da, new PropertyPath("(controlToAnimate.RenderTransform).(TransformTranslate.X)"));
sb.Children.Add(da);
return sb;
}
private void btnNext_Click(object sender, RoutedEventArgs e)
{
SlideEffect(spCarousel, -200).Begin();
}

How to add a focus style to an editable ComboBox in WPF

I've been looking at the following example on how to style the ComboBox, but I haven't been able to create a focus effect when going into an editable combo box. Whenever the ComboBox receives focus, it should go into edit mode and the component should have a focus style.
The basic problem is that whenever I go into the edit mode, it's not the surrounding ComboBox which actually has the focus, but the text subcomponent and I haven't been able to create a Trigger on the text component which modifies the ComboBox's border style since I don't know how to refer to the parent component from the trigger.
I've tried adding ControlTemplate Trigger on the TextBox, or style trigger. I've tried to refer to the ComboBox by name or by using the TemplateBinding option, but without any luck. A simple example would be very appreciated.
Bind IsKeyboardFocusWithin to IsDropDownOpen
<ComboBox ItemsSource="{Binding SortedItems}"
StaysOpenOnEdit="True"
IsDropDownOpen="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource Self}, Mode=OneWay}" />
private void cmbSpecialHandling_GotFocus(object sender, RoutedEventArgs e)
{
Thickness th = new Thickness(2);
cmbSpecialHandling.BorderThickness = th;
cmbSpecialHandling.BorderBrush = this.FindResource("TabFocusColor") as SolidColorBrush;
}
private void cmbSpecialHandling_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
Thickness th = new Thickness(2);
cmbSpecialHandling.BorderThickness = th;
cmbSpecialHandling.BorderBrush = this.FindResource("TabFocusColor") as SolidColorBrush;
}
private void cmbSpecialHandling_LostFocus(object sender, RoutedEventArgs e)
{
cmbSpecialHandling.BorderBrush = Brushes.Transparent;
}
Set the border brush of combobox in its Gotfocus and make it transparent in lost focus:
private void comboBox_GotFocus(object sender, RoutedEventArgs e)
{
Thickness th = new Thickness(2);
comboBox.BorderThickness = th;
comboBox.BorderBrush = this.FindResource("TabFocusColor") as SolidColorBrush;
or
comboBox.BorderBrush = Brushes.Green;
}
private void comboBox_LostFocus(object sender, RoutedEventArgs e)
{
comboBox.BorderBrush = Brushes.Transparent;
}

Resources