|
|||||||||||||||||||||
|
|||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
IntroductionThe main focus of the article is to show you what steps you need to perform to build a custom control for Silverlight 2.0 and reuse that in your Silverlight Projects. The article is based on Silverlight 2.0 Beta1 which was announced today at MIX08. In the article we will create a Control Library and implement our own Let's get started. Creating the ProjectCreate a Silverlight Class Library Project in Visual Studio 2008.
Because this will be a Control Library we've to add a reference to In the next step we will add [assembly: System.Windows.Markup.XmlnsDefinition
("http://schemas.eyedea.hu/silverlight/2008/xaml/presentation", "Eyedea.Controls")]
Creating the control classRename Next we'll add our XAML file which will hold the default styles for the controls in this Control Library. Let's add a Text File type of item to the Project, named
Select the
It's time to edit our main target: Add a using statement for the At this point our using System.Windows.Controls;
namespace Eyedea.Controls
{
public class MediaButton : Button
{
public MediaButton()
{
}
}
}
Adding the default style to our controlOpen First, add the default content to the XAML file and a reference to our Xml namespace. <ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Eyedea.Controls;assembly=Eyedea.Controls">
</ResourceDictionary>
Please note the Add the <Style TargetType="local:MediaButton">
<Setter property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MediaButton">
<Grid x:Name="RootElement">
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Within a The current button design has a fixed width and height so we've to set them with property setters. Tip: The simple property setters should be placed after the <!-- Common properties -->
<Setter property="IsEnabled" Value="true" />
<Setter property="IsTabStop" Value="true" />
<Setter property="Margin" Value="0" />
<Setter property="HorizontalContentAlignment" Value="Center" />
<Setter property="VerticalContentAlignment" Value="Center" />
<Setter property="Cursor" Value="Arrow" />
<Setter property="Foreground" Value="#CC808080" />
<!-- Text related properties -->
<Setter property="TextAlignment" Value="Left" />
<Setter property="TextWrapping" Value="NoWrap" />
<Setter property="FontSize" Value="11" />
<!-- Default Size Constraints -->
<Setter property="Width" Value="50" />
<Setter property="MinWidth" Value="50" />
<Setter property="MaxWidth" Value="50" />
<Setter property="Height" Value="22" />
<Setter property="MinHeight" Value="22" />
<Setter property="MaxHeight" Value="22" />
Add the visual elements to the template by copying the following XAML content of a style which was the result of our first Expression Design How-Do-I video. The design contains a background rectangle, an outline one, and two highlights which will be animated during user interaction. Add the following content inside the <Grid.Resources>
<Storyboard x:Key="MouseOver State">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="HighlightTop"
Storyboard.Targetproperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0.3"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="HighlightBottom"
Storyboard.Targetproperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Border"
Storyboard.Targetproperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0.7"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Pressed State">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="HighlightTop"
Storyboard.Targetproperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="HighlightBottom"
Storyboard.Targetproperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0.3"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Border"
Storyboard.Targetproperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0.5"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Normal State" />
<Storyboard x:Key="Disabled State">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="HighlightTop"
Storyboard.Targetproperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1500000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="HighlightBottom"
Storyboard.Targetproperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1500000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="ContentPresenter"
Storyboard.Targetproperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1500000" Value="0.7"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<Rectangle Fill="#FF000000" Margin="2,2,2,2" RadiusX="1" RadiusY="1" Opacity="0.3"/>
<Rectangle x:Name="Border" Stroke="#FF808080" RadiusX="2" RadiusY="2" Opacity="0.3"/>
<Path x:Name="HighlightTop" Margin="2,2,2,11" Opacity="0.2"
Data="M0,1 C0,0.45 0.45,0 1,0 L45,0 C45.55,0 46,0.45 46,1 C46,1 46,9 46,9
C46,9 0,9 0,9 C0,9 0,1 0,1 z">
<Path.Fill>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFFFFFFF" Offset="0"/>
<GradientStop Color="#FFE1E1E1" Offset="1"/>
</LinearGradientBrush>
</Path.Fill>
</Path>
<Path x:Name="HighlightBottom" Margin="2,11,2,2" Opacity="0" Data="M0,0 C0,0 31,0
46,0 C46,0 46,8 46,8 C46,8.55 45.55,9 45,9 L1,9 C0.45,9 0,8.55 0,8 C0,8
0,0 0,0 z">
<Path.Fill>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFD6D6D6" Offset="0"/>
<GradientStop Color="#FFFFFFFF" Offset="1"/>
</LinearGradientBrush>
</Path.Fill>
</Path>
<ContentPresenter x:Name="ContentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontStretch="{TemplateBinding FontStretch}"
FontStyle="{TemplateBinding FontStyle}"
FontWeight="{TemplateBinding FontWeight}"
Foreground="{TemplateBinding Foreground}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
TextAlignment="{TemplateBinding TextAlignment}"
TextDecorations="{TemplateBinding TextDecorations}"
TextWrapping="{TemplateBinding TextWrapping}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
/>
Build the Project. If everything goes fine at this point you've a working Custom Control Library. Testing the ControlTo test this control we have to create a Silverlight Application Project. In Solution Explorer, right click the Solution's node and add a new Project to the Solution of type Silverlight Application.
For Silverlight Application Visual Studio asks us about the testing method we like to use for this Silverlight Application. For now, a test HTML page will be fine for us.
For real world scenarios like mashups a Web Application needed since the access of external resources are different for Silverlight Applications which runs from the FileSystem or for applications running from a WebServer. Mark the TestApplication Project as our StartUp Project by right clicking the Project's node and selecting "Set as StartUp Project".Adding our control to the Test ProjectTo use the control in our TestApplication we've to add a reference to the Control Library Project.
Open up The test page will contain a 4 by 3 Grid and 2 Overwrite the content of <UserControl x:Class="TestApplication.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:eyedea="clr-namespace:Eyedea.Controls;assembly=Eyedea.Controls"
Width="320" Height="240">
<Grid x:Name="LayoutRoot" Background="Black" Margin="50,50,50,50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.RenderTransform>
<ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2" ScaleY="2" />
</Grid.RenderTransform>
<Rectangle Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1"
Stroke="#FF808080" RadiusX="2" RadiusY="2" Opacity="0.3"/>
<eyedea:MediaButton Grid.Column="1" Grid.Row="1" Margin="2,2,2,2"
Content="Play">
</eyedea:MediaButton>
<eyedea:MediaButton Grid.Column="2" Grid.Row="1" Margin="2,2,2,2"
Content="Stop">
</eyedea:MediaButton>
</Grid>
</UserControl>
Hit F5 and try out the control. For Silverlight 2.0 keyboard support is much better than it was in Silverlight 1.0. Now you get full Tabbing support out of the box. Try this out by pressing Tab several times to get into the Silverlight content from the browser. What's next
Points of Interest
History
| ||||||||||||||||||||