Moving on from Windows & Web Forms to Silverlight 2.0?
In my recent efforts to get familiar with Silverlight it became apparent to me that the first basic skill to build strongly was LAYOUT! I decided that to really create a profound sense of ease and understanding I would need firstly to become as fluent as possible in laying out my UI in this new environment. This was something that I had begun to take for granted in Windows and Web Forms after years of experience had been ploughed into those technologies. Given the nature of XAML based UI’s it was clear that this was not just going to be a ’shift of tools’ kind of experience but more a ’shift of paradigm’ experience altogether. XAML based UI’s are of course declarative and whilst it’s true that ASP.Net UI design is declarative to some degree by virtue of its being ultimately rooted in HTML, Windows Forms is quite a different beast and XAML is after all the new UI technology of the desktop and carries with it the hopes and dreams of those that were swept away in the past by the ActiveX and Java Applet phenomenon’s that promised so much and did not ultimately deliver.
Layout of Windows and Web Forms can be a very designer IDE driven experience (more so in Windows Forms) and it became immediately apparent that the tools (Blend and VS.NET) are not currently as established in as the ‘old guard’, however I do believe that this temporary circumstance offers an upside. Having to dig deeper into the XAML because the tools require you too, makes for developing a deeper understanding and at this early stage that will turn into a definite plus - there are always advantages to knowing how to tweak deep under the hood. I have known developers to live in blissful ignorance of the low level details and never question what all the designer code was doing but in my opinion this isn’t an option with Silverlight right now as the designers are not yet mature or sophisticated enough to abstract us away from the goo so deeply quite yet.
Let’s compare the two experiences by way of example. In the first instance we will build a completely trivial and useless UI that is simply only useful in demonstrating the difference of approaches.
Figure 1.0
(note the lines in the middle is splitter being dragged)
As you may see from figure 1.0, we have a toy form with two panels split by a System.Windows.Forms.Splitter, throw in some docking and you very quickly have a dynamically growing and shrinking UI. The code for this would not be described as declarative however and courteousey of our VS.Net designer generated code all this gets built in a ‘form_name.designer.cs’ file which developers should in fact make their mission in life to avoid changing as it’s a practice that’s encumbered with the age old Code Gen problem of loss of synchronisation.
Listing 1.0
partial class Form1 { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name=”disposing”>true if managed resources should be /// disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.panel1 = new System.Windows.Forms.Panel(); this.splitter1 = new System.Windows.Forms.Splitter(); this.panel2 = new System.Windows.Forms.Panel(); this.button1 = new System.Windows.Forms.Button(); this.textBox1 = new System.Windows.Forms.TextBox(); this.textBox2 = new System.Windows.Forms.TextBox(); this.textBox3 = new System.Windows.Forms.TextBox(); this.textBox4 = new System.Windows.Forms.TextBox(); this.button2 = new System.Windows.Forms.Button(); this.panel1.SuspendLayout(); this.panel2.SuspendLayout(); this.SuspendLayout(); // // panel1 // this.panel1.Controls.Add(this.textBox2); this.panel1.Controls.Add(this.textBox1); this.panel1.Controls.Add(this.button1); this.panel1.Dock = System.Windows.Forms.DockStyle.Top; this.panel1.Location = new System.Drawing.Point(0, 0); this.panel1.Name = “panel1″; this.panel1.Size = new System.Drawing.Size(463, 120); this.panel1.TabIndex = 0; // // splitter1 // this.splitter1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.splitter1.Dock = System.Windows.Forms.DockStyle.Top; this.splitter1.Location = new System.Drawing.Point(0, 120); this.splitter1.Name = “splitter1″; this.splitter1.Size = new System.Drawing.Size(463, 10); this.splitter1.TabIndex = 1; this.splitter1.TabStop = false; // // panel2 // this.panel2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.panel2.Controls.Add(this.button2); this.panel2.Controls.Add(this.textBox4); this.panel2.Controls.Add(this.textBox3); this.panel2.Dock = System.Windows.Forms.DockStyle.Fill; this.panel2.Location = new System.Drawing.Point(0, 130); this.panel2.Name = “panel2″; this.panel2.Size = new System.Drawing.Size(463, 168); this.panel2.TabIndex = 2; // // button1 // this.button1.Location = new System.Drawing.Point(279, 23); this.button1.Name = “button1″; this.button1.Size = new System.Drawing.Size(152, 53); this.button1.TabIndex = 0; this.button1.Text = “button1″; this.button1.UseVisualStyleBackColor = true; // // textBox1 // this.textBox1.Location = new System.Drawing.Point(24, 23); this.textBox1.Name = “textBox1″; this.textBox1.Size = new System.Drawing.Size(158, 20); this.textBox1.TabIndex = 1; // // textBox2 // this.textBox2.Location = new System.Drawing.Point(23, 56); this.textBox2.Name = “textBox2″; this.textBox2.Size = new System.Drawing.Size(158, 20); this.textBox2.TabIndex = 2; // // textBox3 // this.textBox3.Location = new System.Drawing.Point(20, 37); this.textBox3.Name = “textBox3″; this.textBox3.Size = new System.Drawing.Size(161, 20); this.textBox3.TabIndex = 0; // // textBox4 // this.textBox4.Location = new System.Drawing.Point(20, 72); this.textBox4.Name = “textBox4″; this.textBox4.Size = new System.Drawing.Size(162, 20); this.textBox4.TabIndex = 1; // // button2 // this.button2.Location = new System.Drawing.Point(279, 37); this.button2.Name = “button2″; this.button2.Size = new System.Drawing.Size(152, 54); this.button2.TabIndex = 2; this.button2.Text = “button2″; this.button2.UseVisualStyleBackColor = true; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(463, 298); this.Controls.Add(this.panel2); this.Controls.Add(this.splitter1); this.Controls.Add(this.panel1); this.Name = “Form1″; this.Text = “Form1″; this.panel1.ResumeLayout(false); this.panel1.PerformLayout(); this.panel2.ResumeLayout(false); this.panel2.PerformLayout(); this.ResumeLayout(false); } #endregion private System.Windows.Forms.Panel panel1; private System.Windows.Forms.TextBox textBox2; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.Button button1; private System.Windows.Forms.Splitter splitter1; private System.Windows.Forms.Panel panel2; private System.Windows.Forms.Button button2; private System.Windows.Forms.TextBox textBox4; private System.Windows.Forms.TextBox textBox3; }
Clearly all this code builds our UI step wise fashion at run time. In XAML however you state your intention declaratively and the runtime takes that stated intention and displays it for you in the form of a UI. This Windows Form was entirely built using Drag and Drop and required no tweaking by hand. To do a similar type of thing in Silverlight of course we would expect to look quite a bit different. Note the use of the GridSplitter which is not a standard Silverlight control, it is part of the Silverlight Control Set which is available on CodePlex.
Listing 2.0 and Figure 2.0 below both demonstrate a similar layout concept in Silverlight however the difference is that it’s totally declarative, the runtime will determine how to render to the UI based on the stated intent of the XAML. In essence the theme of this post is really about what I found important for me in making the switch over to the XAML based UI technologies and that was to firstly become as comfortable and familiar in laying out my UI as I have been in the already existing UI frameworks. Once this goal is achieved it’s on to integrating familiar patterns and frameworks with XAML such as MVC / MVP and IoC.
Listing 2.0
<UserControl xmlns:basics=”clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls” x:Class=”LayoutSilverlightUserControls.Page” xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” Width=”400″ Height=”300″> <Grid x:Name=”LayoutRoot” Background=”White” Width=”400″ Height=”400″> <Grid.RowDefinitions> <RowDefinition Height=”*” MinHeight=”100″/> <RowDefinition Height=”Auto” /> <RowDefinition Height=”100*” MinHeight=”200″/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition /> </Grid.ColumnDefinitions> <basics:GridSplitter x:Name=”grsplSplitter” Grid.Row=”1″ Grid.Column=”0″ VerticalAlignment=”Center” HorizontalAlignment=”Stretch” Background=”Black” ShowsPreview=”False” Height=”2″> </basics:GridSplitter> <StackPanel Grid.Row=”0″ Grid.Column=”0″ Orientation=”Vertical” VerticalAlignment=”Bottom” Margin=”10″> <StackPanel Orientation=”Horizontal” Margin=”5″> <TextBox Width=”300″></TextBox> <Button Width=”60″ Content=”Button1″></Button> </StackPanel> <StackPanel Orientation=”Horizontal” Margin=”5″> <TextBox Width=”300″></TextBox> <Button Width=”60″ Content=”Button2″></Button> </StackPanel> </StackPanel> <StackPanel Grid.Row=”2″ Grid.Column=”0″ Orientation=”Vertical” VerticalAlignment=”Top” Margin=”10,0,0,0″> <StackPanel Orientation=”Horizontal” Margin=”5″> <TextBox Width=”300″></TextBox> <Button Width=”60″ Content=”Button3″></Button> </StackPanel> <StackPanel Orientation=”Horizontal” Margin=”5″> <TextBox Width=”300″></TextBox> <Button Width=”60″ Content=”Button4″></Button> </StackPanel> </StackPanel> </Grid> </UserControl>
Figure 2.0
How quickly will people start working in WPF in deference to Windows Forms or ASP.Net Web Forms? What are the core set of questions that need answering before choosing the right technology? Subject of a latter post no doubt.
No comments








