Win Form user control not visible in WPF xaml - wpf

I have a xaml start up form in which I am trying to host a windows form control which is a splash screen displaying Product Name / License stuff.. Here is the xaml code which I am using to host the user control but its not at all visible. Not in the designer nor when I run the application actually... Whats wrong in this?
<Window
x:Class="StartupWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wf="clr-namespace:namespace;assembly=assemblyName"
mc:Ignorable="d" x:Name="splashWindow"
WindowStyle="None" ResizeMode="NoResize" Width="500" Height="400"
AllowsTransparency="True" Background="Transparent" ShowInTaskbar="False" Topmost="True"
>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Unloaded">
<BeginStoryboard>
<Storyboard x:Name="board">
<DoubleAnimation Storyboard.TargetName="splashWindow" Storyboard.TargetProperty="Opacity" From="1.0" To="0" Duration="0:0:1.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid x:Name="LayoutRoot">
<Grid x:Name="Splash" Width="450" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,100,0,0">
<Grid x:Name="Back">
<Grid.Effect>
<DropShadowEffect ShadowDepth="1" Direction="-90" BlurRadius="10" Opacity="0.25"/>
</Grid.Effect>
<Border Background="Black" CornerRadius="3" Opacity="0.15"/>
<Border CornerRadius="2" Margin="1" Background="#229C47"/>
</Grid>
<Grid x:Name="Content_Area" Margin="12">
<Image x:Name="Image" Stretch="None" Height="99" Grid.Row="1"/>
<TextBlock x:Name="Info" TextWrapping="Wrap" Text="Starting..." Grid.Row="2" Margin="12,12,12,0" Foreground="White"/>
</Grid>
</Grid>
<WindowsFormsHost Height="325" Name="splashControl" Margin="54,12,64,24" Width="460" HorizontalAlignment="Center" Background="Transparent">
<wf:SplashControl />
</WindowsFormsHost>
</Grid>
</Window>

I'm fighting with the same problem now.
The problem here is the AllowsTransparency="True" of the window, that is incompatible with showing WinForms controls with WindowsFormsHost.
Take a look here.

Related

WPF anchor Grid OpacityMask for Moving Grid Content

I have a hexagonal Polygon that I am trying to use as an OpacityMask, then have content inside the polygon that can scroll and be clipped at the edges. The problem I encounter is that as the content moves, the OpacityMask moves with it (though by a different amount). Below is my code:
<Window Title="MainWindow" Height="450" Width="800">
<Grid Height="450" Width="800">
<StackPanel>
<Grid ClipToBounds="True">
<Grid.OpacityMask >
<VisualBrush Stretch="None" >
<VisualBrush.Visual>
<Polygon Points="220,225 310,69 490,69 580,225 490, 381 310, 381" Fill="Black" />
</VisualBrush.Visual>
</VisualBrush>
</Grid.OpacityMask>
<Polygon Points="220,225 310,69 490,69 580,225 490, 381 310, 381" Stroke="Black" StrokeThickness="5"/>
<Rectangle x:Name="TestRectangle" Height="400" Width="400" Fill="Red" />
</Grid>
<Button Content="Testing" >
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Storyboard.TargetName="TestRectangle" Storyboard.TargetProperty="Margin"
BeginTime="0:0:0" Duration="0:0:0.5" To="-400,0,0,0"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
</StackPanel>
</Grid>
</Window>
How do I anchor the opacity mask so that the grid content can move with the mask remaining stationary?
Edit: Answer Results and Additional Testing
Using the code in an answer provided, I still get movement of the hexagon:
Begin:
Begin State
End:
End State
However, I have found that by adding a second rectangle that is transparent and that moves in the opposite direction of the red rectangle, I achieve the desired result. While this does work, it seems like there should be a better way to do it.
If you try to set the margin of the rectangle directly, you would notice that it is ignored inside a grid. So one way to solve that would be to put the rectangle inside a border and animate the margin for that border
<Window x:Class="StackverflowTests.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StackverflowTests"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Height="450" Width="810">
<StackPanel>
<Grid ClipToBounds="True">
<Grid.OpacityMask >
<VisualBrush Stretch="None" >
<VisualBrush.Visual>
<Polygon Points="220,225 310,69 490,69 580,225 490, 381 310, 381" Fill="Black" />
</VisualBrush.Visual>
</VisualBrush>
</Grid.OpacityMask>
<Polygon Points="220,225 310,69 490,69 580,225 490, 381 310, 381" Stroke="Black" StrokeThickness="5"/>
<Border x:Name="TestRectangle">
<Rectangle Height="400" Width="400" Fill="#ff0000"/>
</Border>
</Grid>
<Button Content="Testing" >
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Storyboard.TargetName="TestRectangle" Storyboard.TargetProperty="Margin"
BeginTime="0:0:0" Duration="0:0:0.5" To="-400,0,0,0" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
</StackPanel>
</Grid>

WPF: How to Style my form with Transperancy levels

I want to implement this kind of Window:
So currently i have this Style :
<Window x:Class="CGTransparent.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="AboutDlg"
Opacity="0.75"
ResizeMode="NoResize"
SizeToContent="WidthAndHeight"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
AllowsTransparency="True" Height="300"
Width="500"
ShowInTaskbar="False"
Background="#00000000">
<Window.Resources>
<LinearGradientBrush x:Key="GradientBrush" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Black" Offset="0.1" />
<GradientStop Color="#202020" Offset="0.25" />
<GradientStop Color="#303030" Offset="0.50" />
<GradientStop Color="#404040" Offset="0.75" />
<GradientStop Color="#505050" Offset="1.0" />
</LinearGradientBrush>
</Window.Resources>
<Border CornerRadius="15" DockPanel.Dock="Top" Background="{DynamicResource GradientBrush}" Margin="0" Padding="0" BorderBrush="Black" BorderThickness="0">
<Grid Margin="0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="500" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="300" />
</Grid.RowDefinitions>
</Grid>
</Border>
</Window>
Result (ignore the tiger...):
Any idea how to achieve this example Style ?
Update:
<Window x:Class="app.Forms.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PacketPlayer.Forms"
mc:Ignorable="d"
WindowStartupLocation="CenterOwner"
AllowsTransparency="True" WindowStyle="None"
Title="Window1" Height="300" Width="300">
<Border BorderBrush="Transparent" BorderThickness="1" CornerRadius="20">
<Grid>
<Image Source="C:\Users\racr\Desktop\download.jpg" Stretch="Fill" Margin="-60">
<Image.Effect>
<BlurEffect KernelType="Gaussian" Radius="60" />
</Image.Effect>
</Image>
<Border CornerRadius="60" Margin="30" Background="#7F000000">
<TextBlock Foreground="White"
FontSize="20" FontWeight="Light" TextAlignment="Center"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Run Text="Hello World" FontSize="48"/>
<LineBreak/>
<Run Text="walterlv.github.io"/>
</TextBlock>
</Border>
</Grid>
</Border>
</Window>
Result:
enter image description here
You cannot simulate your original image with only GradientBrush, you should blur an image with a large amount of blur radius.
Options to simulate it
It's sad to tell you that you cannot implement the iOS blur style exactly as it shows for you.
But, we have three other methods to simulate this kind of style (on Windows 10) and each has its advantages and disadvantages.
Call the Windows internal API SetWindowCompositionAttribute. You can get a lightly blurred transparent Window but this transparency is much less than the iOS one.
Add a BlurEffect to the window background image. You can get a more similar visual effect like the iOS one with very poor performance. But in this way, the background image is fixed and cannot be updated when the window moves.
Use UWP instead of WPF and use the AcrylicBrush. You can get a high-performance blur transparent window. But you should try the UWP Application development.
How to implement them
SetWindowCompositionAttribute API
Calling SetWindowCompositionAttribute API is not very easy, so I've written a wrapper class for easier usage. You can use my class by writing only a simple line in the XAML file or in the cs file.
<Window x:Class="CGTransparent.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:interop="clr-namespace:Walterlv.Demo.Interop"
mc:Ignorable="d" Title="AboutDlg" Height="350" Width="525"
interop:WindowBlur.IsEnabled="True"
Background="Transparent">
</Window>
Or you can use it in the cs file like this:
public class Window1 : Window
{
public Window1()
{
InitializeComponent();
WindowBlur.SetIsEnabled(this, true);
}
}
Just add my wrapper class into your project. It's a very long class so I pasted into GitHub: https://gist.github.com/walterlv/752669f389978440d344941a5fcd5b00.
I also write a post for its usage, but it's not in English: https://walterlv.github.io/post/win10/2017/10/02/wpf-transparent-blur-in-windows-10.html
WPF BlurEffect
Just set the Effect property of a WPF UIElement.
<Window x:Class="MejirdrituTeWarqoudear.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
AllowsTransparency="True" WindowStyle="None"
Width="540" Height="360">
<Grid>
<Image Source="YourImageFile.jpg" Stretch="Fill" Margin="-60">
<Image.Effect>
<BlurEffect KernelType="Gaussian" Radius="60" />
</Image.Effect>
</Image>
<Border CornerRadius="60" Margin="30" Background="#7F000000">
<TextBlock Foreground="White"
FontSize="20" FontWeight="Light" TextAlignment="Center"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Run Text="Hello World" FontSize="48"/>
<LineBreak/>
<Run Text="walterlv.github.io"/>
</TextBlock>
</Border>
</Grid>
</Window>
Notice that it has a very poor performance.
UWP AcyclicBrush
You can read Microsoft's documents Acrylic material - UWP app developer | Microsoft Docs for more details about how to write an AcylicBrush.
Update
You can add a RectangleGeometry to clip your UIElement into a rounded rectangle.
<Window x:Class="MejirdrituTeWarqoudear.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="540" Height="360">
<Grid>
<Grid.Clip>
<RectangleGeometry RadiusX="60" RadiusY="60" Rect="30 30 480 300" />
</Grid.Clip>
<Image Source="High+Sierra.jpg" Stretch="Fill" Margin="-60">
<Image.Effect>
<BlurEffect KernelType="Gaussian" Radius="60" />
</Image.Effect>
</Image>
<Border Background="#7F000000">
<TextBlock Foreground="White"
FontSize="20" FontWeight="Light" TextAlignment="Center"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Run Text="Hello World" FontSize="48"/>
<LineBreak/>
<Run Text="walterlv.github.io"/>
</TextBlock>
</Border>
</Grid>
</Window>

WPF Adorner Newbee

Using VB.Net & WPF
I'm Using Code Available at Overlaying Controls in WPF with Adorners (Converted to VB.Net)
MainWindow.xaml
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid Name="G1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text=" This is Parent Control " HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button Grid.Row="1" Content="Show Child Control " HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click"/>
</Grid>
</Window>
Code Behind
Class MainWindow
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
Dim U1 As New UserControl1
Using OverlayAdorner(Of UserControl).Overlay(G1, U1)
End Using
End Sub
End Class
UserControl1.xaml
UserControl x:Class="UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Background=" #44000000">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="1" Background="White" HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text=" This is Child Control " HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5"/>
<TextBox Name="T1" Grid.Row="1" Margin="5"/>
<Button Grid.Row="2" Content="Close Child Control " HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click" Margin="5"/>
</Grid>
</Grid>
</UserControl>
Code Behind
Public Class UserControl1
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
End Sub
Public Property UserInput As String
Get
Return T1.Text
End Get
Set(value As String)
T1.Text = value
End Set
End Property
End Class
Now when user clicks on button in mainwindow, usercontrol1 should open as adorner and allow user to enter some text in textbox and when user clicks button in usercontrol1 it should close and return text to mainwindow where it would be displayed as message box.
Please Help me to achive the same as i'm newbie in wpf
I attempted to write a pure xaml based solution, you may adjust as per your needs
in this sample there are 2 textboxes 1st is regular while other popups a list when focused and allow you to select an item from it
sample code
<Grid>
<Grid.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Grid.Resources>
<StackPanel HorizontalAlignment="Center"
VerticalAlignment="Center"
MinWidth="200">
<TextBox Text="regular textbox" />
<TextBox Text="{Binding SelectedItem,ElementName=list,TargetNullValue=select an item}">
<TextBox.Triggers>
<EventTrigger RoutedEvent="GotFocus">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="button"
Storyboard.TargetProperty="IsChecked">
<DiscreteBooleanKeyFrame Value="true"
KeyTime="0:0:0" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBox.Triggers>
</TextBox>
</StackPanel>
<Border Background="#77000000"
Visibility="{Binding IsChecked,ElementName=button,Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="300"
Height="150">
<ListBox x:Name="list">
<sys:String>item 1</sys:String>
<sys:String>item 2</sys:String>
<sys:String>item 3</sys:String>
<sys:String>item 4</sys:String>
<ListBox.Triggers>
<EventTrigger RoutedEvent="MouseLeftButtonUp">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="button"
Storyboard.TargetProperty="IsChecked">
<DiscreteBooleanKeyFrame Value="False"
KeyTime="0:0:0" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ListBox.Triggers>
</ListBox>
<ToggleButton IsChecked="False"
x:Name="button"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Content="X"
ToolTip="Close" />
<Grid.Effect>
<DropShadowEffect Opacity=".5" />
</Grid.Effect>
</Grid>
</Border>
</Grid>
content of the grid inside the border is where you'll place your user control
just copy this code to a new project's main window and run it. give it a try and see if this is close to your needs, we can work out to fit it according to your needs.

Close popup from child button's press?

I have a Popup that contains a "close" button. The popup is opened by a toggle button (its IsOpen property is bound to a ToggleButton as provided by this answer). How can I close the popup when the button is pressed? This is my XAML:
<Canvas x:Name="LayoutRoot">
<ToggleButton x:Name="ToggleButton"
Style="{DynamicResource ToggleButtonStyle}" Height="51" Canvas.Left="2.999" Width="50.333" IsHitTestVisible="{Binding ElementName=Popup, Path=IsOpen, Mode=OneWay, Converter={StaticResource BoolInverter}}"/>
<Popup x:Name="Popup" IsOpen="{Binding IsChecked, ElementName=ToggleButton}" StaysOpen="False" AllowsTransparency="True">
<Canvas Height="550" Width="550">
<Grid Height="500" Width="500" Canvas.Left="25" Canvas.Top="25" d:LayoutOverrides="Width, Height, Margin">
<Grid.Effect>
<DropShadowEffect BlurRadius="15" ShadowDepth="0"/>
</Grid.Effect>
<Grid.RowDefinitions>
<RowDefinition Height="0.132*"/>
<RowDefinition Height="0.868*"/>
</Grid.RowDefinitions>
<Rectangle x:Name="Background" Fill="#FFF4F4F5" Margin="0" Stroke="Black" RadiusX="6" RadiusY="6" Grid.RowSpan="2"/>
<Border x:Name="TitleBar" BorderThickness="1" Height="70" VerticalAlignment="Top" Margin="0,0.5,0,0" CornerRadius="5">
<DockPanel>
<TextBlock TextWrapping="Wrap" Text="FOOBAR POPUP TITLE" FontSize="24" FontFamily="Arial Narrow" Margin="17,0,0,0" d:LayoutOverrides="Height" VerticalAlignment="Center" FontWeight="Bold"/>
<Button x:Name="CloseButton" Content="Button" VerticalAlignment="Center" DockPanel.Dock="Right" HorizontalAlignment="Right" Margin="0,0,13,0" Style="{DynamicResource CloseButtonStyle}"/>
</DockPanel>
</Border>
<Border BorderThickness="1" Height="413" Grid.Row="1" Background="#FF2F2F2F" Margin="12">
<Rectangle Fill="#FFF4F4F5" RadiusY="6" RadiusX="6" Stroke="Black" Margin="12"/>
</Border>
</Grid>
</Canvas>
</Popup>
</Canvas>
A better approach than code behind is to use an event trigger on the button click event:
<Button>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsChecked" Storyboard.TargetName="ToggleButton">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
Disclaimer: I haven't run this code through VS so it might have a typo or 2
Other answers didn't work for me, because I was using a DataTemplate for the buttons inside the popup. After lot's of searching I found that I should use Storyboard.Target instead of Storyboard.TargetName. Otherwise the x:Name was not found and there was some namespace exception.
<ToggleButton x:Name="MyToggleButtonName" Content="{Binding MyToggleButtonString}"/>
And later inside the Popup that has a ListBox which is populated from some ItemsSource:
<ListBox.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name, Mode=OneWay}"
Command="{StaticResource MyCommandThatTakesAParameter}"
CommandParameter="{Binding Name}">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsChecked" Storyboard.Target="{Binding ElementName=MyToggleButtonName}">
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
This way it is possible to get a somewhat working ComboBox which can execute commands with the buttons inside it. (A normal ComboBox can't launch commands for some odd reason.)
One way of doing it is to add event handler for your CloseButton:
<Button x:Name="CloseButton" Click="OnButtonClick" Content="Button" VerticalAlignment="Center" DockPanel.Dock="Right" HorizontalAlignment="Right" Margin="0,0,13,0" Style="{DynamicResource CloseButtonStyle}"/>
And in OnButtonClick event handler set state of your
TuggleButton.IsChecked = false;
I have't tested code in VS, so there might be some typos

Modify Silverlight Resource in VisualState

I am wondering if there is an easy way to modify some kind of shared resource (i.e. a Brush) of a control between different VisualStates. For example, I would like to define a Brush to use as both the Background of a Border and the Fill of a different Rectangle. In a different VisualState I would like to change this background Brush in one place (the resource) and have it reflected in all elements using the resource.
I am not sure if resources can really be referenced by Name (not Key) for the TargetName of the Storyboard in the VisualState.
Here is a simplified example of what I am trying to do in XAML:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SilverlightApplication.MainPage"
Width="200" Height="200">
<UserControl.Resources>
<SolidColorBrush x:Name="Background" x:Key="Background" Color="Black" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MyStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Red">
<Storyboard>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Color)">
<EasingColorKeyFrame KeyTime="00:00:00" Value="Red"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border Background="{StaticResource Background}" Width="100" Height="100" HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="Red" BorderThickness="1"/>
<Rectangle Fill="{StaticResource Background}" Width="100" Height="100" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
</Grid>
</UserControl>
I have a feeling because these are StaticResources in Silverlight they are only loaded once and can not be changed. I know WPF has some concept of DynamicResources. Is there any way to achieve this type of behavior in Silverlight without having to redefine my brush in all elements?
DynamicResources unfortunately don't exist in Silverlight.
Some people use Bindings.
There's a sneaky way to simulate the experience within a single UserControl that you might want to try.
All that's happening in the code below is that the Storyboard animates a single rectangle's Fill, which is then bound to the other Fill's in the UserControl by using Element binding. The source rectangle doesn't need to be visible for this to work.
<UserControl x:Class="TestSilverlightStuff.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestSilverlightStuff"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<SolidColorBrush x:Key="Background" Color="Black" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MyStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Red">
<Storyboard>
<ColorAnimation Duration="0" To="Red" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="trickyRectangle" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle Fill="Black" x:Name="trickyRectangle" Visibility="Collapsed" />
<Border Background="{Binding Fill, ElementName=trickyRectangle}" Width="100" Height="100" HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="Red" BorderThickness="1"/>
<Rectangle Fill="{Binding Fill, ElementName=trickyRectangle}" Width="100" Height="100" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
<Button Content="Button" Height="57" HorizontalAlignment="Left" Margin="12,231,0,0" Name="button1" VerticalAlignment="Top" Width="153" Click="button1_Click" />
</Grid>
</UserControl>
Here's the C# button click code:
private void button1_Click(object sender, System.Windows.RoutedEventArgs e)
{
VisualStateManager.GoToState(this, "Red", true);
}
It's not as elegant as a DynamicResource, but it works in some cases.

Resources