When I migrated my blog over to a new provider and blogengine, I lost some images,replaced them using VS2010, so some screenshots look 'newer'.
Series - Create a UserControl with Silverlight 2.0 Beta x
Part I - Create a UserControl with Silverlight 2.0 Beta 1 (this post)
Part II - Create a UserControl with SilverLight 2.0 Beta
Wanting to know what all the hype is really about, I started to think about creating a web application with Silverlight.
Before I will create an application, my idea is to start of with a UserControl. A really simple one too. For the application I am going to maybe be building with Silverlight, I need a UI component to choose the gender of a person.
You could use two radiobuttons, make them a member of the same group and we're off. But with Silverlight we can try a more graphical approach, maybe a more intuitive control. I want to create a control that has the Male and Female Symbol that are clickable, through clicking on a symbol you select the gender.
I installed:
- Microsoft Expression Design
- Microsoft Expression Blend 2.5 March 2008 Preview
- Microsoft Visual Studio 2008
- Microsoft Silverlight Tools Beta 1 for Visual Studio 2008
First thing you learn when starting to use this technology is that you really need a designers eye on things. So if you are not a creative person, that likes designing stuff, maybe you need a designer to do it for you.
We are going to try to do the design ourselves for now.
Create Solution and projects
First I Fired up Visual Studio 2008. I created a new Silverlight Application (so it is easy to try our control out).
Create Silverlight Application
As soon as you click OK, you are presented a choice, because Silverlight will be hosted on or inside a web page, you have to choose from the following options:
- Create only the Silverlight app and let Studio generate an HTML page for you to test the app with (only in bin/debug)
- Add a Website project to your solution
- Add a Web Application Project to your solution
Select hosting application type
I choose option 3. a Web Application Project. Now I got two projects inside my solution. I right click on the Page.xaml file and choose "Open in Expression Blend"
Open in MS Blend
Blend
Rightclick on the Silverlight project file and choose "Add New Item..." from the menu
Add New Item
Select UserControl as template and give the control a name.
New Item
Rightclick in the area named: "Objects and Timeline" in the left side of Blend, on the UserControl and select Rename, give the control a name (GenderChoose), it cannot be the same as the name you gave the .xaml file (this is confusing, because the New Item dialog suggests you name the Usercontrol, but all you do is name the xaml and these names both must be unique.
Rename Control
Because the background of the LayoutRoot is white We need to change it to transparent, we do this by selecting the LayoutRoot inside the UserControl
Select LayoutRoot
After this,we select the little square that is on the right of the BackGround Brush setting
Background brush
In the contextmenu choose "Reset" and the background is transparent
No brush
Design
Now it is time to fire up Microsoft Expression Design, it is a vector based drawing and design tool. I need to create the Male and Female symbols with it.
Click File > New and create a document with Width: 120 px and Height 140 px.
From the toolbox select an Ellipse
Select Ellipse
Draw a circle and select a line, to draw the arrow on the upper right of the circle. Set the width of the line to 10px. You should be making something like this:
Male Symbol
Select all paths in your drawing, than click Object > Compound Path > Make, or use Ctrl + 8. Than again select all on your drawing
Compounded path
and paste into your control in Blend.
Path inside Blend Control
Rename the Path to MalePath. Do the same for the Female symbol (draw, make compound path, copy and paste into Blend) and rename this path into FemalePath. Give the paths a color you like, by selecting and choosing the right color in Brush option. Now we got something like this
Colors added
And the result in Xaml is this:
1: <UserControl
2: xmlns="http://schemas.microsoft.com/client/2007"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5: xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6: mc:Ignorable="d"
7: x:Class="HC.Silverlight.Tyout.GenderChooser"
8: d:DesignWidth="288"d:DesignHeight="160"x:Name="GenderChoose">
9:
10: <Gridx:Name="LayoutRoot"Height="160"Width="244">
11: <Pathx:Name="MalePath"
12: MouseLeftButtonDown="MalePath_MouseLeftButtonDown"
13: MouseEnter="MalePath_MouseEnter"
14: MouseLeave="MalePath_MouseLeave"
15: Stretch="Fill"StrokeThickness="10"
16: StrokeLineJoin="Round"
17: Stroke="#4C0E1B4B"
18: Data="M71.182777,43.484818 C88.632889,57.770176 91.340874,83.323097 77.231247,
19: 100.56004 C63.121323,117.79601 37.536755,120.18899 20.086346,
20: 105.90402 C2.6360354,91.620079 -0.071950652,66.066154 14.037977,
21: 48.829205 C28.147804,31.592951 53.732468,29.20006 71.182777,
22: 43.484818 z M71.687004,42.605003 L102.30298,5.2050009 L104.313,
23: 34.850189 M71.437004,42.401001 L102.053,5.000001 L72.594521,8.885973"
24: Height="120.23"
25: HorizontalAlignment="Left"
26: Margin="2.93199992179871,2.15100002288818,0,37.6189994812012"
27: VerticalAlignment="Stretch"
28: Width="109.313"
29: d:LayoutOverrides="Width"/>
30: <Pathx:Name="FemalePath"
31: MouseLeftButtonDown="FemalePath_MouseLeftButtonDown"
32: MouseEnter="FemalePath_MouseEnter"
33: MouseLeave="FemalePath_MouseLeave"
34: Stretch="Fill"
35: StrokeThickness="10"
36: StrokeLineJoin="Round"
37: Stroke="#4CF502E4"
38: Data="M 75.6667,46.1667C 98.2183,46.1667 116.5,64.2245 116.5,86.5C 116.5,108.775 98.2183,126.833 75.6667,
39: 126.833C 53.1151,126.833 34.8333,108.775 34.8333,86.5C 34.8333,64.2245 53.115,46.1667 75.6667,
40: 46.1667 Z M 76.5,126.5L 76.5,185.167M 103.833,159.167L 48.8333,159.167"
41: HorizontalAlignment="Left"
42: Margin="122.833000183105,0.166999995708466,0,10.8330001831055"
43: Width="91.667"
44: d:LayoutOverrides="Width"/>
45: </Grid>
46: </UserControl>
Listing 1
Now we open Visual studio again, we get the file modified message
We select Yes to all and in the upper side of the Studio Design screen we click reload.
We open the code window for our GenderChooser class (GendserChooser.xaml.cs) and I wrote the following code:
1: namespace HC.Silverlight.Tryout
2: {
3: #region Enums
4: /// <summary>
5: /// Tells which Gender
6: /// </summary>
7: publicenum GenderChoice
8: {
9: /// <summary>
10: /// Gender for man
11: /// </summary>
12: Male = 0,
13: /// <summary>
14: /// Gender for woman
15: /// </summary>
16: Female = 1,
17: /// <summary>
18: /// Not sure :-)
19: /// </summary>
20: Unknown = 2
21: }
22:
23: #endregion
24:
25: #region Delegates
26: /// <summary>
27: /// Handles GenderChosen Event
28: /// </summary>
29: /// <param name="sender"></param>
30: /// <param name="e"></param>
31: publicdelegatevoid GenderChosenEventHandler(object sender, GenderChoice gender);
32: #endregion
33:
34: publicpartialclass GenderChooser : UserControl
35: {
36: #region Events
37: /// <summary>
38: /// GenderChosen
39: /// </summary>
40: publicevent GenderChosenEventHandler GenderChosen;
41: #endregion
42:
43: #region EventHandler
44: /// <summary>
45: /// Raises event, if EventHandler not null
46: /// </summary>
47: /// <param name="message"></param>
48: privatevoid OnGenderChosen(object sender, GenderChoice selectedGender)
49: {
50: if (GenderChosen != null)
51: {
52: GenderChosen(sender, selectedGender);
53: }
54: }
55: #endregion
56:
57:
58: #region Privates
59: private GenderChoice _Gender = GenderChoice.Unknown;
60: private SolidColorBrush _MaleColor = new SolidColorBrush(Color.FromArgb(255, 14, 27, 75));
61: private SolidColorBrush _MaleColorDisabled = new SolidColorBrush(Color.FromArgb(70, 14, 27, 75));
62: private SolidColorBrush _FemaleColor = new SolidColorBrush(Color.FromArgb(255, 245, 2, 228));
63: private SolidColorBrush _FemaleColorDisabled = new SolidColorBrush(Color.FromArgb(70, 245, 2, 228));
64: #endregion
65:
66: #region Properties
67:
68: #region Colors
69: /// <summary>
70: /// Gets or sets MaleColorDisabled, the color if the Male symbol is disabled
71: /// </summary>
72: public SolidColorBrush MaleColorDisabled
73: {
74: get { return _MaleColorDisabled; }
75: set { _MaleColorDisabled = value; }
76: }
77:
78: /// <summary>
79: /// Gets or sets FemaleColorDisabled, the color if the Female symbol is disabled
80: /// </summary>
81: public SolidColorBrush FemaleColorDisabled
82: {
83: get { return _FemaleColorDisabled; }
84: set { _FemaleColorDisabled = value; }
85: }
86:
87: /// <summary>
88: /// Gets or sets MaleColor
89: /// </summary>
90: public SolidColorBrush MaleColor
91: {
92: get { return _MaleColor; }
93: set { _MaleColor = value; }
94: }
95:
96: /// <summary>
97: /// Gets or sets FemaleColor
98: /// </summary>
99: public SolidColorBrush FemaleColor
100: {
101: get { return _FemaleColor; }
102: set { _FemaleColor = value; }
103: }
104: #endregion
105:
106: /// <summary>
107: /// Gets or sets GenderChoice
108: /// </summary>
109: public GenderChoice Gender
110: {
111: get { return _Gender; }
112: set
113: {
114: _Gender = value;
115: SetColorAccordingToChoice();
116: OnGenderChosen(this, _Gender);
117: }
118: }
119: #endregion
120:
121: #region C'tor
122: public GenderChooser()
123: {
124: // Required to initialize variables
125: InitializeComponent();
126:
127: }
128: #endregion
129:
130: #region MouseEvents
131: privatevoid MalePath_MouseEnter(object sender, MouseEventArgs e)
132: {
133: MalePath.Stroke = MaleColor;
134: }
135:
136: privatevoid MalePath_MouseLeave(object sender, MouseEventArgs e)
137: {
138: if (Gender == GenderChoice.Male)
139: {
140: MalePath.Stroke = MaleColor;
141: }
142: else
143: {
144: MalePath.Stroke = MaleColorDisabled;
145: }
146: }
147:
148: privatevoid FemalePath_MouseEnter(object sender, MouseEventArgs e)
149: {
150: FemalePath.Stroke = FemaleColor;
151: }
152:
153:
154: privatevoid FemalePath_MouseLeave(object sender, MouseEventArgs e)
155: {
156: if (Gender == GenderChoice.Female)
157: {
158: FemalePath.Stroke = FemaleColor;
159: }
160: else
161: {
162: FemalePath.Stroke = FemaleColorDisabled;
163: }
164: }
165:
166:
167: privatevoid MalePath_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
168: {
169: Gender = GenderChoice.Male;
170: }
171:
172: privatevoid FemalePath_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
173: {
174: Gender = GenderChoice.Female;
175: }
176:
177: #endregion
178:
179: #region Private Methods
180: /// <summary>
181: /// Sets color for Male and Female according to Gender chosen
182: /// </summary>
183: privatevoid SetColorAccordingToChoice()
184: {
185: switch (Gender)
186: {
187: case GenderChoice.Unknown:
188: MalePath.Stroke = MaleColorDisabled;
189: FemalePath.Stroke = FemaleColorDisabled;
190: break;
191: case GenderChoice.Female:
192: MalePath.Stroke = MaleColorDisabled;
193: FemalePath.Stroke = FemaleColor;
194: break;
195: case GenderChoice.Male:
196: MalePath.Stroke = MaleColor;
197: FemalePath.Stroke = FemaleColorDisabled;
198: break;
199: }
200: }
201: #endregion
202: }
203: }
Listing 2
I use the SolidColorBrush to change the color of the symbols, (I only change the Alpha channel). I decided to make properties for the colors, that way the colors are dynamic.
An enum is used for the Gender choice, a property Gender of type GenderChoice (the enum) holds the current Gender.
In the setter for Gender the method SetColorAccordingToChoice is called in this method the current Gender is read and accordingly the richt colors are set on the symbols.
Control in action
The control in action, the first picture shows the control in startup state (symbols greyed out), the second picture shows the female symbol selected, under the hood the Gender is filled with GenderChoice.Female and the GenderChosen Event is fired.
All in all I think Silverlight is cool for it's purpose. It is possible to create strong graphics for your application and use them programming the language you already are used to.
The fact that not everybody is a designer is really the downside. A lot of developers will be better of creating windows or web apps using standard controls.
Ofcourse with Silverlight 2.0 standard controls are available, but the strong point of Silverlight is it's decoupling of UI from logic.
When designers are going to adopt Blend and MS Design, it could be really taking off, but until that time we have to do it ourselves.
Series - Create a UserControl with Silverlight 2.0 Beta x
Part I - Create a UserControl with Silverlight 2.0 Beta 1 (this post)
Part II - Create a UserControl with SilverLight 2.0 Beta
Henry Cordes
My thoughts exactly...