Update ImageBrush from ResourceDictionary at runtime - silverlight

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;
}

Related

How show contents of wpf window in stack panel

i want to show contents of window in wpf when click on button
i think will use container controls like stake panel but doesn't work
private void RibbonButton_Click(object sender, RoutedEventArgs e)
{
Window1 w1 = new Window1();
stkShow.Children.Add(w1);
}
You need to use the content of the window you want to use as child.
This worked for me.
private void RibbonButton_Click(object sender, RoutedEventArgs e)
{
Window1 Child = new Window1();
StkPanelContent.Children.Clear();
object content = Child.Content;
Child.Content = null;
Child.Close();
this.stkShow.Children.Add(content as UIElement);
}
I hope it helps.

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;
}

WPF: How to animate color change?

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);
}

Frame navigation with key binding command?

I’d like to load a page into frame with key binding using ‘Ctrl’ and ‘H’ buttons from a keyboard. I can load page. It is working now. I am wondering if I can just override UriSource link with what it is now into frame. I assign UriSources in XML and I need to override one instance instead of introducing new UriSource to keep the index not changed. Any ideas? Thank you in advance!
public partial class MainWindow : Window
{
public static RoutedUICommand LoadShareSelectedCommand = new RoutedUICommand();
public MainWindow()
{
InitializeComponent();
this.CommandBindings.Add(new CommandBinding(LoadShareSelectedCommand, LoadShareSelectedCommandExecuted));
KeyGesture kg = new KeyGesture(Key.H, ModifierKeys.Control);
InputBinding ib = new InputBinding(LoadShareSelectedCommand, kg);
this.InputBindings.Add(ib);
}
private void LoadShareSelectedCommandExecuted(object sender, ExecutedRoutedEventArgs e)
{
this.ContentFrame.NavigationService.Navigate(new Uri("Pages/SharesSelected.xaml", UriKind.Relative));
}
private void LoadShareSelectedCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void NavShareSelected(object sender, RoutedEventArgs e)
{
this.ContentFrame.NavigationService.Navigate(new Uri("Pages/SharesSelected.xaml", UriKind.Relative));
}
}

Refresh Silverlight UserControl via XAML

I'm using the lastest version of Silverlight 2.0 within Visual Studio 2008. I have a simple Silverlight UserControl with the following code:
public partial class SilverlightControl1 : UserControl
{
public SilverlightControl1()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(SilverlightControl1_Loaded);
Composite = new Composite();
}
void SilverlightControl1_Loaded(object sender, RoutedEventArgs e)
{
Composite.Width = this.Width / 2.0;
Composite.Height = this.Height / 2.0;
if (!this.LayoutRoot.Children.Contains(Composite))
this.LayoutRoot.Children.Add(Composite);
}
public Composite Composite
{
get;
set;
}
}
public class Composite : ContentControl
{
private Grid grid;
private Canvas canvas;
public Composite()
{
if (grid == null) grid = new Grid();
if (canvas == null) canvas = new Canvas();
if (!grid.Children.Contains(canvas))
grid.Children.Add(canvas);
Content = grid;
this.Loaded += new RoutedEventHandler(Composite_Loaded);
}
private Rectangle rectangle;
void Composite_Loaded(object sender, RoutedEventArgs e)
{
if (rectangle == null) rectangle = new Rectangle();
Canvas.SetTop(rectangle, 0);
Canvas.SetLeft(rectangle, 0);
rectangle.Fill = new SolidColorBrush(Color);
rectangle.Width = Width;
rectangle.Height = Height;
if (!canvas.Children.Contains(rectangle))
canvas.Children.Add(rectangle);
}
public Color Color
{
get;
set;
}
}
I then use this UserControl in a Silverlight application, the XAML of the page looking like this:
<UserControl x:Class="SilverlightApplication1.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:test="clr-namespace:SilverlightClassLibrary1;assembly=SilverlightClassLibrary1"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="Green">
<test:SilverlightControl1 Name="uControl1">
<test:SilverlightControl1.Composite>
<test:Composite Color="Yellow"/>
</test:SilverlightControl1.Composite>
</test:SilverlightControl1>
</Grid>
</UserControl>
My question is: what code do I have to add to the above so that by changing "Composite Color" to something other than Yellow and hitting the return button, the UserControl automatically refreshes? As the code is, the only way to refresh the UserControl is by moving the Slider bar within the VS2008 IDE which changes the percentage zoom of the Silverlight Page. A side question, although of lesser importance to the above question, is: with the code as it is above, why can't I change the "Background" color of the LayoutRoot? If I remove my UserControl it works as expected.
The solution was two-fold. Firstly to make changes in the LayoutUpdated event rather than the Loaded event and secondly to subscribe to the PropertyChangedCallback of the PropertyMetadata. Here's the complete working code:
public partial class SilverlightControl1 : UserControl
{
public SilverlightControl1()
{
InitializeComponent();
this.LayoutUpdated += new EventHandler(SilverlightControl1_LayoutUpdated);
Composite = new Composite();
}
void SilverlightControl1_LayoutUpdated(object sender, EventArgs e)
{
Composite.Width = this.Width / 2.0;
Composite.Height = this.Height / 2.0;
if (!this.LayoutRoot.Children.Contains(Composite)) this.LayoutRoot.Children.Add(Composite);
}
public Composite Composite
{
get;
set;
}
}
public class Composite : ContentControl
{
private Grid grid;
private Canvas canvas;
public Composite()
{
if (grid == null) grid = new Grid();
if (canvas == null) canvas = new Canvas();
if (!grid.Children.Contains(canvas)) grid.Children.Add(canvas);
Content = grid;
this.LayoutUpdated += new EventHandler(Composite_LayoutUpdated);
}
void Composite_LayoutUpdated(object sender, EventArgs e)
{
if (rectangle == null) rectangle = new Rectangle();
Canvas.SetTop(rectangle, 0);
Canvas.SetLeft(rectangle, 0);
rectangle.Fill = new SolidColorBrush(Color);
rectangle.Width = Width;
rectangle.Height = Height;
if (!canvas.Children.Contains(rectangle)) canvas.Children.Add(rectangle);
}
public static readonly DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(Color), typeof(Composite), new PropertyMetadata(Colors.Red, new PropertyChangedCallback(OnColorPropertyChanged)));
private static void OnColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Composite comp = (Composite)d;
comp.InvalidateArrange();
}
private Rectangle rectangle;
public Color Color
{
get { return (Color)GetValue(ColorProperty); }
set { SetValue(ColorProperty, value); }
}
}
I think you need to make Composite into a Dependency Proprety. Probably will want to do the same thing for Color on Composite so that you'll be able to bind it.

Resources