I’m new to Silverlight and I wanted to accomplish a relatively simple task:
Create a “panel” control that would display a heading and some child content.
I was able to get this work to a degree, but the placement of the XAML really confuses me.
On my page I use my control. This results in my panel being shown with a button in the child content area which is blue, with a 20px yellow heading at the top saying “Below is some content”.
<UserControl x:Class="SilverlightApplication9.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SilverlightApplication9">
<Grid Background="White">
<local:MyPanel Background="Blue">
<Button Width="50" Height="25" Content="Hello"></Button>
</local:MyPanel>
</Grid>
</UserControl>
My panel source code is simple, just:
public partial class MyPanel : ContentControl
{
public MyPanel()
{
DefaultStyleKey = typeof(MyPanel);
InitializeComponent();
}
}
It’s a partial class, and there is an attached XAML file, which is where my confusion starts:
If I try placing my style/template code into the partial class XAML file, it seems to be ignored (my button is shown, but the other content like the colors and text is missing)
<ContentControl x:Class="SilverlightApplication9.MyPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SilverlightApplication9">
<ContentControl.Resources>
<ResourceDictionary>
<Style TargetType="local:MyPanel">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyPanel">
<Grid Background="Yellow">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock HorizontalAlignment="Center" Height="20" Grid.Row="0" Text="Below is some content"/>
<Grid Grid.Row="1" Background="LightBlue">
<ContentPresenter />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</ContentControl.Resources>
</ContentControl>
However if I create a \Themes\generic.xaml file and paste in the same code, it works
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SilverlightApplication9"
xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
>
<Style TargetType="local:MyPanel">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyPanel">
<Grid Background="Yellow">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock HorizontalAlignment="Center" Height="20" Grid.Row="0" Text="Below is some content"/>
<Grid Grid.Row="1" Background="LightBlue">
<ContentPresenter />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
I’m clearly missing something important about how resources or XAML files are processed or used in a project (I did not have any experience with WPF before Silverlight).
What am I doing wrong that is preventing me from just putting the panel’s template code into the panel’s xaml file? Are there some concepts regarding XAML and resources that I’m getting wrong?
David, you need to create a key for your style, and reference it in the panel via it’s Style property … it is a limitation of Silverlight, that it does not let you create “global” styles that apply to all elements of some type.
This behaviour is different when you place the style in themes, as you noticed.
Another alternative is to place the style in the ResourceDictionary of the panel itself and not the page/user control, but then you cannot reuse that style in other panels.