Chapter 4: Introduction to Controls


In this Chapter, I will describe you about some of the most common controls used in Silverlight. After the end of this section, you will be able to understand about those basic controls and their uses. Here I will guide you to understand some of the properties of each control and how to set them from both XAML & Code behind C# file.

To read Silverlight tutorials from begining, click here or you can also read below tutorials.

Introduction to Silverlight
Introduction to Silverlight Application Development
Introduction to Panels

Overview

Silverlight 4 provides a large collection of UI controls for Silverlight application development. These controls are require to do the UI design of the application for giving a better representation to the user. You can customize the look & feel by creating your own Style or extending the control to give more power to the UI. I will describe the control styling in later chapters.

Here is some of the Silverlight 4 controls that I want to describe for you:

  1. TextBlock
  2. TextBox
  3. PasswordBox
  4. RichTextBox
  5. ComboBox
  6. ListBox
  7. CheckBox
  8. RadioButton
  9. Button

TextBlock

TextBlock is the primary element for displaying text inside your Silverlight Application. You will find it useful whenever you want to display some strings. TextBlock is a FrameworkElement available in the System.Windows.Controls namespace. There is a property named “Text” where you have to enter the text string.

<TextBlock Text=”Hello Silverlight” />

This is not necessary for you to use the Text property to set some text inside your TextBlock control. TextBlock control can also be used as a container to set a para of strings. Hard enter to place a line break can be set using the <LineBreak/> control.

<TextBlock>

<TextBlock.Text>

This is the first line of Text.

<LineBreak/>

This is the second line of Text.

</TextBlock.Text>

</TextBlock>

 

OR

 

<TextBlock>

This is the first line of Text.

<LineBreak/>

This is the second line of Text.

</TextBlock>
Also, you can represent a series of strings contained inside different Run elements instead of presenting as a single string. In that scenario, each Run element can have different font attributes set towards it. The LineBreak element will represent an explicit new line break

<TextBlock>

<LineBreak/>

<Run Foreground=”Maroon”FontFamily=”Arial”FontSize=”30″

FontWeight=”Bold”>Arial Bold 30</Run>

<LineBreak/>

<Run Foreground=”Teal”FontFamily=”Times New Roman”FontSize=”18″

FontStyle=”Italic”>Times New Roman Italic 18</Run>

<LineBreak/>

<Run Foreground=”SteelBlue”FontFamily=”Verdana”FontSize=”14″

FontWeight=”Bold”>Verdana Bold 14</Run>

</TextBlock>

TextBlock

You will see various Properties and Events available for TextBlock control to do text formatting and other operation.

TextBlock Properties

TextBox

TextBox is another important element in Silverlight. It is also available inside the System.Windows.Controls. Unlike TextBlock, the TextBox inherits from the base class Control. Whenever you want to enter some text inputs from your user using your Silverlight application, you need the help of TextBox. It is one of the most important input control for Silverlight for data entry.

<TextBox Height=”25″ Width=”200″ Text=”This is a Single Line TextBox”/>

<TextBox Height=”100″ Width=”200″

HorizontalScrollBarVisibility=”Disabled”

VerticalScrollBarVisibility=”Auto”

TextWrapping=”Wrap”

Text=”This is a Multi-Line TextBox. This is a Multi-Line TextBox.”/>

 

publicstaticreadonlyDependencyProperty AcceptsReturnProperty;

Set “AcceptsReturn” to True if you want to insert a Hard line break explicitly in your TextBox by your user. From code behind if you want to set the value to AcceptsReturnProperty of the TextBox, you have to call the SetValue() and then pass the DependencyProperty with the appropriate value:

myTextBox.SetValue(TextBox.AcceptsReturnProperty, true);

myTextBox.SetValue(TextBox.AcceptsReturnProperty, false);

From XAML, you can set it as:

<TextBox AcceptsReturn=”True”/>

 


publicstaticreadonlyDependencyProperty IsReadOnlyProperty;


Set “IsReadOnly” to True if you want your TextBox as only readable by your user. This is very useful when you are putting a Edit Button near your TextBox to give the user chose whether he wants to update some texts.

To set it from the code behind use the same format of the SetValue() method. Here’s the code:

myTextBox.SetValue(TextBox.IsReadOnlyProperty, true);

 

publicstaticreadonlyDependencyProperty MaxLengthProperty;

Set “MaxLength” to a positive numeric value , your user can’t add more than the specified value. Suppose you are setting it to 50, hence after inserting 50 characters the TextBox caret will not go forward.

You can set the Max Length property from code behind C# like this:

myTextBox.SetValue(TextBox.MaxLengthProperty, 150);

publicstaticreadonlyDependencyProperty SelectionBackgroundProperty;

“SelectionBackground” color once set, your selected text will have the specified background. You can set both Solid Brush or Gradient Brush as your selection background. If you want to set it from code behind, use the following convention:

myTextBox.SetValue(TextBox.SelectionBackgroundProperty, newSolidColorBrush(Colors.Black));


 


publicstaticreadonlyDependencyProperty SelectionForegroundProperty;


Like “SelectionBackground” the “SelectionForeground” will set the specified color as the foreground color of the selected text. The property SelectionForeground property can also be set in the same way. In this case, it will change the color of the font for the selected text. Have a look:

myTextBox.SetValue(TextBox.SelectionForegroundProperty, newSolidColorBrush(Colors.Black));

 

publicstaticreadonlyDependencyProperty TextAlignmentProperty

“TextAlignment” is responsible to set the text alignment to left, right, center or justify.

publicstaticreadonly DependencyPropertyTextProperty;

“Text” property contains the Text entered into the TextBox. You can set it in the same way from XAML & Code as I mentioned above.

publicstaticreadonlyDependencyProperty TextWrappingProperty;

Set “TextWrapping” to Wrap so that, if your entered text becomes longer than the specified width of the TextBox, it will populate the remaining text in a separate line (as described in the MultiLineTextBox figure).

PasswordBox

PasswordBox is available inside the System.Windows.Controls and inherits from Control. Whenever you need to add a Password field in your Silverlight application form to give the user access to login with credential, you have to use this password box. You will find it useful when you need to do login.

<PasswordBox Width=”200″ Height=”25″Password=”kunal2383″ />

<PasswordBox Width=”200″ Height=”25″ Password=”kunal2383″PasswordChar=”X” />

Here are some useful DependencyProperty of the PasswordBox:

publicstaticreadonlyDependencyProperty MaxLengthProperty;

Set “MaxLength” to a positive numeric value , your user can’t add more than the specified value. Suppose you are setting it to 50, hence after inserting 50 characters the TextBox caret will not go forward.

publicstaticreadonly Dependency PropertyPasswordCharProperty;

Sets the password character of the control. The default value for password character of the field box is the asterisk (*). But you can change it by setting the value to this dependency property. If you set ‘X ‘ as password character, whatever you enter in the textbox of the field will display as ‘X’.

publicstaticreadonly DependencyPropertyPasswordProperty;

Gets or Sets the password property of the PasswordBox. If you set the text it will be visible in the UI in asterisk format.

publicstaticreadonly DependencyPropertySelectionBackgroundProperty;

“SelectionBackground” color once set, your selected text will have the specified background.

publicstaticreadonly DependencyPropertySelectionForegroundProperty;

Like “SelectionBackground” the “SelectionForeground” will set the specified color as the foreground color of the selected text.

RichTextBox

Like TextBoxRichTextBox also inherits from Control and available in the namespace System.Windows.Controls. It is useful when you want to give a input box to your user where they can able to format the entered text like word processor. You can display text in various text format like Bold, Italic, Underline, Left/Right/Center align, various font size/color etc.

Have a look into the following XAML code where the RichTextBox has several <Paragraph> tag to split the text in various parts. You can use <Bold>,<Italic> tags to format the entered text. You can also align the text or change the font-size or font-color by setting the proper attributes to the <Paragraph> tag.

<RichTextBox Height=”153″Width=”336″AcceptsReturn=”True”>

<Paragraph>

This is a RichTextBox control having multiple paragraphs inside it.

You will find it more useful while creating an Editor control in Silvelight application.

<LineBreak />

</Paragraph>

<Paragraph>

<Bold>This Text is in Bold</Bold>

<LineBreak />

<Italic>This Text is in Italic</Italic>

</Paragraph>

<ParagraphTextAlignment=”Right”>

This Text is Right aligned.

<LineBreak />

</Paragraph>

<ParagraphTextAlignment=”Center”>

<Hyperlink>This is an Hyperlink Button and center aligned</Hyperlink>

</Paragraph>

</RichTextBox>

Here is the output of the above XAML code:

You can see here that, not only formatted text you can also enter hyperlinks to the RichTextBox control. If you set the AcceptsReturn=”True” your user can explicitly enter hard line break by pressing the “Enter” key.

ComboBox

ComboBox is an items control which works like a ListBox but only one item is visible at a time. It inherits from Selector control and available in the System.Windows.Controls namespace. It contains ComboBoxItem which inherits from ListBoxItem. ComboBoxItem is also present in the same namespace as ComboBox is i.e. System.Windows.Controls namespace.

Let us create a simple ComboBox having some contents inside it. Set the Width of the ComboBox to a specific value, let’s say 200 in our case. Now add ComboBoxItem as the Items of the Combo. This step is not always require (in case of XAML atleast). Set some string as the “Content” of the ComboBoxItem. Here you may ask one question, is it only supports text? The answer is “No”. You can also set any FrameworkElement inside the Content of the ComboBoxItem, such as TextBlock, TextBox, Button, Rectangle etc.

Have a look into the XAML code here:

<ComboBox Width=”200″>

<ComboBox.Items>

<ComboBoxItem Content=”Item 01″/>

<ComboBoxItem Content=”Item 02″/>

<ComboBoxItem Content=”Item 03″/>

<ComboBoxItem Content=”Item 04″/>

<ComboBoxItem Content=”Item 05″/>

<ComboBoxItem Content=”Item 06″/>

<ComboBoxItem Content=”Item 07″/>

<ComboBoxItem Content=”Item 08″/>

<ComboBoxItem Content=”Item 09″/>

<ComboBoxItem Content=”Item 10″/>

</ComboBox.Items>

</ComboBox>

The output of the above XAML will initially look like the below figure:

Now once you click on the small arrow at the right side of the ComboBox, you will see a menu comes out from it containing the content you added there:

Here are some properties those you will find useful while working with the ComboBox:

IsDropDownOpen:

Once set to True the drop down will show with the content. By using this property you can programmatically control the visibility of the dropped menu. By default it is set to False and when you click on the small arrow it sets it to True and thus it opens up in the screen.

IsEditable:

From the name you can easily understand the functionality of this property. By default it is set as False. Hence, in the normal scenario you can’t type anything inside the ComboBox. If you want to edit the content of the ComboBox or want to type inside it, just set the value to True.

MaxDropDownHeight:

You can control the size of the drop down menu. If you set it to some numeric value, the height will be set as per the entered value.

ListBox

ListBox inherited from Selector present inside the System.Windows.Controls namespace. It contains ListBoxItem as Items. It represents it’s children as list. The followings are the DependencyProperties of ListBox:

publicstaticreadonlyDependencyProperty IsSelectionActiveProperty;

publicstaticreadonlyDependencyProperty ItemContainerStyleProperty;

publicstaticreadonlyDependencyProperty SelectionModeProperty;

Some important properties are described below:

SelectionMode:

Gets or Sets the Selection Behaviour of ListBox control. There are three different modes of the Selection of the ListBoxItem: Single, where user can select only one ListBoxItem at a time; Multiple, where user can select multiple items without pressing a Modifier Key; Extended, where user can select multiple items by pressing a Modifier Key. The default mode is “Single”.

<ListBox Width=”200″SelectionMode=”Multiple” Height=”200″>

<ListBox.Items>

<ListBoxItem Content=”Item 01″/>

<ListBoxItem Content=”Item 02″/>

<ListBoxItem Content=”Item 03″/>

<ListBoxItem Content=”Item 04″/>

<ListBoxItem Content=”Item 05″/>

<ListBoxItem Content=”Item 06″/>

<ListBoxItem Content=”Item 07″/>

<ListBoxItem Content=”Item 08″/>

<ListBoxItem Content=”Item 09″/>

<ListBoxItem Content=”Item 10″/>

</ListBox.Items>

</ListBox>

The above example shows you how the ListBox looks like in different SelectionMode. The first example demonstrates “Multiple Selection Mode”. This type of listbox you need to give your user a choice to select multiple items. In the second example shows a simple “Single Selection Mode”, where the user can only select a single choice.

CheckBox

Checkbox inherits from ToggleButton and resides inside System.Windows.Controls namespace. Using this you can give your user a choice to select multiple items. There are three different states for CheckBox. If checked will return true, unchecked will return false and the third state returns null value. Generally the third state is not that much useful in normal scenarios. Use “Content” to set value (e.g. string, rectangle etc) to the checkbox.
Have a look into the following example:

<CheckBoxIsChecked=”True”Content=”Set as Checked (True)” />

<CheckBoxIsChecked=”False”Content=”Set as UnChecked (False)” />

<CheckBoxIsThreeState=”True”IsChecked=”{x:Null}”Content=”Set as Third State (Null)” />

<CheckBoxIsEnabled=”False”IsChecked=”True”Content=”Set as Checked, but disabled” />

<CheckBox>

<CheckBox.Content>

<Grid>

<EllipseHorizontalAlignment=”Stretch” Fill=”Red” />

<TextBlock Text=”Multi Element as Checkbox Content” />

</Grid>

</CheckBox.Content>

</CheckBox>

The first code demonstrates the Checked item, the second code demonstrates unchecked item and third code demonstrates the third state. Third states becomes null. In the fourth code you will see the disabled state of the checkbox. What about the fifth code? Yup, in the fifth code we have added a Ellipse and a TextBlock wrapped with a Grid panel. It is not always necessary to set string as content. As per your requirement you can set anything. But be sure that CheckBox.Content only supports a single element and if you want to set multiple elements wrap with a panel as I demonstrated above.

RadioButton

Like CheckBox the element name RadioButton placed inside System.Windows.Controls assembly namespace also inherits from ToggleButton and contains the same properties as described above in CheckBox examples.

<RadioButtonIsChecked=”True” Content=”Set as Checked (True)” />

<RadioButtonIsChecked=”False” Content=”Set as UnChecked (False)” />

<RadioButton>

<RadioButton.Content>

<Grid>

<EllipseHorizontalAlignment=”Stretch” Fill=”Red” />

<TextBlock Text=”Multi Element as RadioButton Content” />

</Grid>

</RadioButton.Content>

</RadioButton>

<RadioButtonGroupName=”MyGroup” Content=”Set under MyGroup”IsChecked=”True” />

<RadioButtonGroupName=”MyGroup” Content=”Set under MyGroup” />

Normally if you are setting multiple radio buttons inside a page, you can select only one of them. If you need your user to select radio button from each different group of your option you can set a group name to the radio button. By grouping the options using a group name will allow your user to select a single radio option from each group.

Button

Button control in Silverlight inherits from ButtonBase class and can be found under the System.Windows.Controls namespace. Button controls are mainly require to Submit forms or for navigation panels. You can style it as per your need.

You can set some text as it’s content or can place any framework element inside it. If you want to add more than one element inside it, you have to use any panel wrapped to your elements.
See the below code on how we can use Button controls:

<StackPanel x:Name=”LayoutRoot” Margin=”20″ Background=”White”>

<Button Content=”I am a button control” Height=”25″ Width=”200″ Margin=”5″ />

<Button Height=”25″ Width=”200″ Margin=”5″>

<Button.Content>

<CheckBox Content=”Checkbox inside Button” />

</Button.Content>

</Button>

<Button Width=”200″>

<Button.Content>

<StackPanel Orientation=”Horizontal”>

<Rectangle Width=”30″ Height=”25″ Fill=”Green” Margin=”0,0,5,0″ />

<TextBlock Text=”Rectangle inside Button” />

</StackPanel>

</Button.Content>

</Button>

</StackPanel>

The first example is a simple button control whereas the second contains checkbox as it’s content. The third example contains a Rectangle and a Text wrapped by Grid panel. This shows how we can use panel to load multiple elements inside a button.

Button has Click event where you can write your logic to do whatever you want once you click on the button e.g. navigation to a different view, submitting the form etc.

Please leave any feedback or suggestions you have about this tutorials. Thanks and keep reading my forthcoming tutorials and articles.

Introduction to Panels – Silverlight tutorial Chapter 3


In this Chapter I will describe about different Panels available in Silverlight. After reading this chapter you will be familiar with various types of Silverlight Panels. As this tutorial is mainly targeted for Silverlight 4, hence you will find some panels unavailable in the earlier versions of Silverlight.

Go to previous chapter – Introduction to Silverlight Application Development

Overview of Panels

There are total six numbers of panels available in Silverlight. They are as below:

  1. Grid
  2. Canvas
  3. StackPanel
  4. ScrollViewer
  5. Border
  6. ViewBox

You will find Grid, Canvas, StackPanel and Border as most useful panel while you start working with them in your Silverlight application. Let us discuss about those in depth.

“Grid” Layout Panel

The Grid layout panel is the most useful panel you ever use. This is the default panel inserted inside every xaml when you create a UserControl. When we created our first Silverlight example or even the first UserControl, you noticed that there was a Grid panel named “LayoutRoot” where we created Rows and Column definitions to place our control to create the Employee View.

The Grid layout control allows you to define the Grid structure to place individual elements as Rows & Column structure in Matrix format. Once you divide your Grid panel in Rows and Columns you can place your element in the appropriate cell by using Grid.Row or Grid.Column property.

 

See the Grid structure in the below image:
Grid layout panel

Picture: Grid Layout Panel Structure

 

Now lets discuss about creating rows and columns, then place some rectangles in each cells. We will create three rows and three columns as described in the above image:

1. Create a UserControl named “GridPanelDemo” in our Silverlight Application.

2. Open the GridPanelDemo.xaml file. You will see that there is a Grid named “LayoutRoot” inside your UserControl.

3. Now enter the following XAML code between the Grid tags (<Grid>…</Grid>):

<Grid.RowDefinitions>

<RowDefinition/>

<RowDefinition/>

<RowDefinition/>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<ColumnDefinition/>

<ColumnDefinition/>

<ColumnDefinition/>

</Grid.ColumnDefinitions>

4. This will divide your Grid in three rows and three columns of equal height and equal width.

5. You can also set height for Rows and widths for Columns by specifying the value to the properties like this:

<RowDefinition Height=”100″/>

and

<ColumnDefinition Width=”100″/>

6. You can specify the value for Height & Width in three different ways:

a. Pixel Value (like: “90”, means the height or width of 90 pixel)
b. Percentage Value (like: “5*”, means the height or width of 50% or “*”, means 100%)
c. Automatic Value (like: “Auto”, means the height or width of the Row or Column will resize automatically as  per the size of content of the respective Row or Column.

7. Now we will put some texts using TextBlock and will put them in appropriate cells of the Grid control. You can achieve this by using the Grid.Row=”ROW_NUMBER” and Grid.Column=”COLUMN_NUMBER” as the property of your TextBlock control. Modify your XAML to set this texts like this:

<Grid x:Name=”LayoutRoot” Background=”BlanchedAlmond”>

<Grid.RowDefinitions>

<RowDefinition/>

<RowDefinition/>

<RowDefinition/>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<ColumnDefinition/>

<ColumnDefinition/>

<ColumnDefinition/>

</Grid.ColumnDefinitions>

<TextBlock Text=”Row[0], Col[0]” Grid.Row=”0″ Grid.Column=”0″ />

<TextBlock Text=”Row[0], Col[1]” Grid.Row=”0″ Grid.Column=”1″ />

<TextBlock Text=”Row[0], Col[2]” Grid.Row=”0″ Grid.Column=”2″ />

<TextBlock Text=”Row[1], Col[0]” Grid.Row=”1″ Grid.Column=”0″ />

<TextBlock Text=”Row[1], Col[1]” Grid.Row=”1″ Grid.Column=”1″ />

<TextBlock Text=”Row[1], Col[2]” Grid.Row=”1″ Grid.Column=”2″ />

<TextBlock Text=”Row[2], Col[0]” Grid.Row=”2″ Grid.Column=”0″ />

<TextBlock Text=”Row[2], Col[1]” Grid.Row=”2″ Grid.Column=”1″ />

<TextBlock Text=”Row[2], Col[2]” Grid.Row=”2″ Grid.Column=”2″ />

</Grid>

8. Also, you can use Grid.RowSpan and Grid.ColumnSpan properties to span your rows and columns. If you are familiar with HTML table tag & properties you can easily understand it properly.

<TextBlock Text=”Row[0], Col[0]” Grid.Row=”0″ Grid.Column=”0″ Grid.RowSpan=”2″ Grid.ColumnSpan=”2″ />

If we use the above code, it will span the 0th Row and 0th Column to two Rows & Columns. This is nothing but merging rows and columns of Grid Layout.

9. Now, open the MainPage.xaml.cs file & in the constructor create the instance of the GridPanelDemo usercontrol and add it as the child of the LayoutRoot i.e. Grid.

LayoutRoot.Children.Add(new GridPanelDemo());

10. Run your Silverlight application. You will see that, the TextBlocks are arranged in the Page in matrix manner.

Grid Layout Panel

Picture: Grid Layout Panel Demo

 

You will find this useful when you have to position your controls in proper way, in proper Row & Column. Note that, if you don’t create rows or columns and place multiple controls inside your naked Grid, you will see them overlapping each other. So, if you are using Grid be sure that you splitted your Grid in proper rows and columns.

“Canvas” Layout Panel

Canvas is the simplest layout available in Silverlight. It is very easy to understand and using this you can place any content any where inside the canvas. Not only this, you can also layered your application and by layering you can put your content front or back of any other control.

You can think Canvas as a HTML div Tag, where you can put your content in specific location by providing absolute left and top position. Have a look into the below image to get a brief idea on the same.
Canvas Panel

Picture: Canvas Layout Panel Structure

 

Lets think there are two Rectangles placed inside the Canvas as mentioned in the above figure. The first Rectangle (Blue one) is placed at the (10, 10) position. This is the coordinate location of your first Rectangle. First one stands for “Left” and second one stands for “Top”. So, What is the coordinate position of the second Rectangle (Orange one)? Exactly, it is Left =50 and Top = 30 i.e. (50, 30).
I think it is the right time to go for writing a sample code to create the above canvas with two Rectangles inside it. I am pretty much confident that, you have now a good confidence on the Canvas positioning.

Let us create a new UserControl named “CanvasPanelDemo” and then we will create two Rectangles in it and will place it in proper location.

1. Create a UserControl named “CanvasPanelDemo” in our Silverlight Application.

2. Open the CanvasPanelDemo.xaml file. You will see that there is a Grid named “LayoutRoot” inside your UserControl.

3. Now replace your Grid tag (<Grid>…</Grid>) with a Canvas tag (<Canvas>…</Canvas) and set the background color as Green:

<Canvas Background=”Green” >

</Canvas>

4. Now, open your MainPage.xaml.cs file and modify your constructor to load the newly created CanvasPanelDemo Usercontrol in page load as a child to your LayoutRoot Grid:

LayoutRoot.Children.Add(new CanvasPanelDemo());

5. If you run your application now, you will see that your Canvas has taken the full screen of your browser window. Why? You didn’t set the Height & Width of your UserControl and placed inside a Grid. That’s why it took the full size of the browser window and that’s why you can see your Green canvas taking the whole screen.

6. We will now create two Rectangles and place it inside the Canvas. For the first time, we will not set any position to the rectangles. Lets see what happens then. Modify your XAML to look like this:

<Canvas Background=”Green” >

<Rectangle x:Name=”rectFirst” Fill=”Blue” Height=”80″ Width=”120″/>

<Rectangle x:Name=”rectSecond” Fill=”Orange” Height=”100″ Width=”150″/>

</Canvas>

7. If you run your application again, you will see only one Rectangle present inside your Canvas. Which one? Yes, only the orange one. So, there you will ask “We added two Rectangle, one Green and another Orange. But why only the orange one is visible in the UI? What happened to the first rectangle?” So, my answer will be “Nothing happened to any of your added control. They all are placed inside the Canvas”.

Yes, that’s right. All the two rectangles are available inside your canvas. As we didn’t specify the position of the rectangles and the second rectangle is bigger than the first one, it placed on top of the other i.e. the orange one placed on top of the green rectangle. Whatever control you add at the end of the Canvas will have a higher Z-Index which places your control on top of the other. I will discuss on this later in this chapter.

Canvas Panel

Picture: Canvas Panel Demo 1 (without position)

8. Now, lets go for positioning the rectangles. We will set coordinate position (50, 50) to the first rectangle and coordinate position (200, 100) to the second rectangle. For doing this, we have to set the Canvas.Left and Canvas.Top properties of each Rectangle. Have a look into the following code. You will understand easily how to do this.

<Canvas Background=”Green”>

<Rectangle x:Name=”rectFirst” Fill=”Blue” Height=”80″ Width=”120″

Canvas.Left=”50″ Canvas.Top=”50″ />

<Rectangle x:Name=”rectSecond” Fill=”Orange” Height=”100″ Width=”150″

Canvas.Left=”200″ Canvas.Top=”100″ />

</Canvas>

9. Run your application and you will notice that the first rectangle has been placed at (Left=50, Top=50) location and the second one has been placed at (Left=200, Top=100) location. Your application will look similar to this:

Canvas Panel with proper position

Picture: : Canvas Panel Demo 2 (with proper position)

 

10. Now if you want to play around it, just modify your XAML to place the rectangle controls in various positions inside the canvas.

 

I think you are now familiar with positioning silverlight controls inside the Canvas. Let us discuss something on the Z-Index property. Z-Index stands for layering out your Silverlight application. If you are familiar with Photoshop you knew that, photoshop creates layers to position them on top of each other. Those who don’t know about it can learn it from here.

Suppose you want to create an application where two rectangles are there (similar to the previous example) and one rectangle is partially blocking the another. You have to write a logic to modify your application such that, when you click on the first rectangle it will come front of the another. Similar kind of logic for the second rectangle too.

 

So, how can we develop this? We have to use the Z-Index property for each rectangle. Lets say we will set the Z-Index of the first rectangle to 1 (one) and the second rectangle to 2 (two). Initially the second rectangle is blocking the first one partially. Now once you click on the first rectangle we will set the Z-Index of it to 2 and the Z-Index of the other rectangle to 1. As the Z-Index of the first rectangle is greater than the second it will come on top of the other. The same behaviour will be for the second rectangle. Once we click on the second rectangle (which is hiding behind the first) will come top the other will go behind. For doing this, we will set the Z-Index of the first rectangle to 1 and the second to 2.

1. Open the CanvasPanelDemo.xaml file and modify the Rectangle properties of Canvas.Left and Canvas.Top to place the rectangle on top of each other.

2. Now add the Canvas.ZIndex property to each rectangle. Set it to 1 for the first rectangle and set it to 2 for the second rectangle. After these modifications your xaml will look like this:

<Canvas Background=”Green”>

<Rectangle x:Name=”rectFirst” Fill=”Blue” Height=”80″ Width=”120″

Canvas.Left=”50″ Canvas.Top=”50″ Canvas.ZIndex=”1″ />

<Rectangle x:Name=”rectSecond” Fill=”Orange” Height=”100″ Width=”150″

Canvas.Left=”92″ Canvas.Top=”74″ Canvas.ZIndex=”2″ />

</Canvas>

3. Run your Silverlight application and you will see them in action. You will see the orange rectangle blocking a part of the blue rectangle.
Canvas Panel Demo

Picture: Panel Demo (ZIndex – 1)

 

4. Now let us write some logic to code behind (C#) to change the ZIndex property of the rectangles. To do this, first we will register the MouseLeftButtonDown event of both the rectangles in the constructor:

public CanvasPanelDemo()


{


InitializeComponent();

rectFirst.MouseLeftButtonDown += (rectFirst_MouseLeftButtonDown);

rectSecond.MouseLeftButtonDown += (rectSecond_MouseLeftButtonDown);


}


 

5. Now in the MouseLeftButtonDown event of the first rectangle we will set the ZIndex of the first rectangle to 2 and the second rectangle to 1. This will cause the first rectangle to come on top of the second rectangle.

privatevoid rectFirst_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)


{


Canvas.SetZIndex(rectFirst, 2);

Canvas.SetZIndex(rectSecond, 1);


}


 

6. In the MouseLeftButtonDown event of the second rectangle we will set the ZIndex of the first rectangle to 1 and the second rectangle to 2. This will cause the second rectangle to come on top of the first one.

privatevoid rectSecond_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)


{


Canvas.SetZIndex(rectFirst, 1);

Canvas.SetZIndex(rectSecond, 2);


}


 

7. Run your application to see it in action. At the initial time the second rectangle will be on top of the first one. When you click on the first rectangle it will come in front. Once you click on the second rectangle the first will go behind and thus the second rectangle will come at the front.

Canvas Panel Demo - ZIndex 2

Picture: Canvas Panel Demo (ZIndex – 2)

 

Canvas Panel Demo (ZIndex - 3)

Picture: Canvas Panel Demo (ZIndex – 3)

 

 

“StackPanel” Layout Panel

StackPanel is one of the most important panel in Silverlight. You will find it useful when you want to show some of your Silvelright elements either Horizontally or Vertically. It has a property called “Orientation”. You can set it appropriately as per your requirement.

Once you add some elements inside StackPanel, you will notice that they will place as a Stack on top of each other. Have a look into the following figure to get a clear understanding of the same.

Picture: StackPanel Orientation (Horizontal & Vertical)

 

Let us create an example to showcase the StackPanel demo:

1. Create a UserControl named “StackPanelDemo” in your Silverlight project

2. Now, open your MainPage.xaml.cs file and modify your constructor to load the newly created StackPanelDemo Usercontrol in page load as a child to your LayoutRoot Grid:

LayoutRoot.Children.Add(new StackPanelDemo());

3. Open the StackPanelDemo.xaml file and inside the Grid tag named “LayoutRoot” we will add two StackPanels (one Horizontal and another Vertical) with some Rectangles as Children.

4. The following XAML code will create a Vertical StackPanel which consists of four rectangles of different colors:

<StackPanel Orientation=”Vertical” Background=”SkyBlue” Height=”200″

Width=”100″ Grid.Column=”0″>

<Rectangle Height=”50″ Width=”100″ Fill=”Red” />

<Rectangle Height=”50″ Width=”100″ Fill=”Green” />

<Rectangle Height=”50″ Width=”100″ Fill=”Blue” />

<Rectangle Height=”50″ Width=”100″ Fill=”Yellow” />

</StackPanel>

5. The following code will create a Horizontal StackPanel which also contains four rectangles of different colors:

<StackPanel Orientation=”Horizontal” Background=”SkyBlue” Height=”100″

Width=”300″ Grid.Column=”1″>

<Rectangle Height=”100″ Width=”60″ Fill=”Red” />

<Rectangle Height=”100″ Width=”60″ Fill=”Green” />

<Rectangle Height=”100″ Width=”60″ Fill=”Blue” />

<Rectangle Height=”100″ Width=”60″ Fill=”Yellow” />

</StackPanel>

6. Now run your application and you will notice the following UI of your StackPanel Demo application. The left panel is your Vertical StackPanel whereas the right panel is the Horizontal StackPanel.

StackPanel Demo

Picture: StackPanel Demo

 

 

“ScrollViewer” Layout Panel

ScrollViewer is another layout container, which you will find interesting in some cases. Though it is not require to use in all the scenarios to hold elements but to show contents inside a scrollable panel like ListBox or Editor window you have to use ScrollViewer. ListBox, TextBox, RichTextBox internally uses ScrollViewer to implement the scrolling functionality.

Now come the question of implementing the scrollviewer functionality to our previous sample of StackPanel demo. If you add more Rectangles in the Vertical StackPanel in the previous demo application, you will notice that the rectangles are cropping inside the StackPanel as it has a fix height of 100. Now do the following to implement the scrolling functionality in the Vertical StackPanel:

1. Open the StackPanelDemo.xaml file to edit our previous XAML file

2. Remove the Height & Grid.Column properties from the StackPanel

3. Surround the StackPanel with ScrollViewer tag (<ScrollViewer> … </ScrollViewer>) and set the Height of the ScrollViewer to 200. Also add the Grid.Column = “0” to the ScrollViewer.

4. Add some more rectangles inside the StackPanel, so that, the ScrollBar got enabled for the ScrollViewer. After the modification of your XAML will look like this:

<ScrollViewer Height=”200″Grid.Column=”0″>

<StackPanel Orientation=”Vertical” Background=”SkyBlue” Width=”100″>

<Rectangle Height=”50″ Width=”100″ Fill=”Red” />

<Rectangle Height=”50″ Width=”100″ Fill=”Green” />

<Rectangle Height=”50″ Width=”100″ Fill=”Blue” />

<Rectangle Height=”50″ Width=”100″ Fill=”Yellow” />

<Rectangle Height=”50″ Width=”100″ Fill=”Red” />

<Rectangle Height=”50″ Width=”100″ Fill=”Green” />

<Rectangle Height=”50″ Width=”100″ Fill=”Blue” />

<Rectangle Height=”50″ Width=”100″ Fill=”Yellow” />

<Rectangle Height=”50″ Width=”100″ Fill=”Red” />

<Rectangle Height=”50″ Width=”100″ Fill=”Green” />

<Rectangle Height=”50″ Width=”100″ Fill=”Blue” />

<Rectangle Height=”50″ Width=”100″ Fill=”Yellow” />

</StackPanel>

</ScrollViewer>

5. If you run the application now, you will see a ScrollBar on the right side of the panel. Thus it make your Rectangles to scroll properly.

ScrollViewer Panel Demo

Picture: ScrollViewer Panel Demo

 

Here note that, we set the Height to the ScrollViewer and not to the StackPanel. The reason behind this is, if you set the Height of the StackPanel it will have a fix height, thus it will not create the Scrolling behaviour. As we set the Height to the ScrollViewer the StackPanel height increases as and when you add child to it but the ScrollViewer here does a great job and creates a scrollbar cropping the StackPanel to the height of the ScrollViewer.

 

 

“Border” Layout Panel

It’s an another type of Layout Panel in Silverlight. But as like other panels it can’t contain multiple contents in it. Border supports only one child as a content. If you want to use Border as a container of multiple controls, you have to wrap those with anyother panel like Grid, Canvas etc. and then place it in the Border. So, what is Border actually? The name says it. It is a border. If we want to add some border in our Silverlight application, we can use it at that time.

Look into the following figure. Here you will see four different shapes. These shapes you can create using Border element. You can create your border filled with Solid color or Gradient color or you can use a transparent color.

Border Panel Example

Picture: Border Panel Example

 

After seeing the above figure, I think one question came to you mind that “I can create the same thing using the Rectangle too. Then what is the benefit of using Border?” Yes right. You can create the same thing using Rectangle too as we did earlier, but the main difference is “You can create a rounded corner shape using Border. It has the property called “CornerRadius”. If you set it to 45, means your shape will have a corner radius of 45 degree.

Let us create some borders in a demo application:

1. Create a UserControl named “BorderDemo” in your Silverlight project

2. Now, open your MainPage.xaml.cs file and modify your constructor to load the newly created BorderDemo Usercontrol in page load as a child to your LayoutRoot Grid:

LayoutRoot.Children.Add(new BorderDemo());

3. Open the BorderDemo.xaml file and inside the Grid tag named “LayoutRoot” we will add a Border as Content.

4. Let us add the first Border of Height=100 and Width=150 with a brown colored BorderThickness of 2:

<Border Height=”100″ Width=”150″ BorderThickness=”2″ BorderBrush=”Brown”/>

Once run in browser you will see the following view:

Border Panel Demo 1

Picture: Border Panel Demo 1

 

5. Now we will modify this border to create a Rounded Corner border. To do this, we will add a property “CornerRadius” to it. We will set the value to 25 i.e. 25 degree. Your modified XAML will look like this:

<Border Height=”100″ Width=”150″ CornerRadius=”25″ BorderThickness=”2″ BorderBrush=”Brown”/>

Border Panel Demo 2

Picture: Border Panel Demo 2

 

6. Now we will change it a little to set a background color to it. Border has a property called “Background”. You can set the color there which you like. Here is the modified XAML of the same:

<Border Height=”100″ Width=”150″ CornerRadius=”25″ BorderThickness=”2″ BorderBrush=”Brown” Background=”Brown”/>

If you run your Silverlight application now, you will see the following:

Border Panel Demo 3

Picture: Border Panel Demo 3

 

7. Let us modify it a little bit more to add a child inside it. We will put a Text “I am a TextBlock inside Border control”. Put the below code in your XAML. You will notice that I placed a TextBlock inside the <Border> … </Border> tag. You can place any control or panel inside the Border like this.

<Border Height=”100″ Width=”250″ CornerRadius=”25″ BorderThickness=”2″ BorderBrush=”Brown” Background=”Brown”>

<TextBlock Text=”I am a TextBlock inside Border control”

VerticalAlignment=”Center”

HorizontalAlignment=”Center”/>

</Border>

 

Once you run, it will show similar to this:

Border Panel Demo 4

Picture: Border Panel Demo 4

 

Remember that, you can add only one child to the Border panel. If you need to add more than one child, add a different panel like Grid, Canvas or StackPanel inside the Border and then add the child elements to that panel. Think before chosing your panels.

 

 

“ViewBox” Layout Panel

ViewBox panel is another useful panel in Silverlight. It is actually not a new panel in Silverlight. It was available in Silverlight 3 toolkit, but Microsoft added it in the Silverlight 4 runtime for it’s demand. You can use ViewBox panel to stretch and scale a element control. Like Border it also has only and only one child. If you want to set more than one child, you have to use any other panel inside the ViewBox to hold other children controls.

As I told earlier, you can stretch and scale your control inside your ViewBox. It has a property called “Stretch” which has the following values:
1. Fill:

If you set the Stretch property to Fill, the content will fill the entire space of the ViewBox. It doesn’t preserve the aspect ratio.

<Viewbox Stretch=”Fill” MaxWidth=”100″ MaxHeight=”100″ Name=”viewBox1″>

<Image Source=”images/microsoft_silverlight.jpg”/>

</Viewbox>

<Viewbox Stretch=”Fill”MaxWidth=”200″ MaxHeight=”200″ Name=”viewBox2″>

<Image Source=”images/microsoft_silverlight.jpg”/>

</Viewbox>

<Viewbox Stretch=”Fill”MaxWidth=”300″ MaxHeight=”300″ Name=”viewBox3″>

<Image Source=”images/microsoft_silverlight.jpg”/>

</Viewbox>

 


//Set the Stretch property to Fill


privatevoid stretchFill(object sender, RoutedEventArgs e)


{


viewBox1.Stretch = Stretch.Fill;

viewBox2.Stretch = Stretch.Fill;

viewBox3.Stretch = Stretch.Fill;


}


ViewBox Demo 1

Picture: ViewBox Demo 1

 

2. None:
If you set the Stretch property to None, the content will preserve its original size.

<Viewbox Stretch=”Fill” MaxWidth=”100″ MaxHeight=”100″ Name=”viewBox1″>

<Image Source=”images/microsoft_silverlight.jpg”/>

</Viewbox>

<Viewbox Stretch=”Fill”MaxWidth=”200″ MaxHeight=”200″ Name=”viewBox2″>

<Image Source=”images/microsoft_silverlight.jpg”/>

</Viewbox>

<Viewbox Stretch=”Fill”MaxWidth=”300″ MaxHeight=”300″ Name=”viewBox3″>

<Image Source=”images/microsoft_silverlight.jpg”/>

</Viewbox>

//Set the Stretch property to None

privatevoid stretchNone(object sender, RoutedEventArgs e)


{


viewBox1.Stretch = Stretch.None;

viewBox2.Stretch = Stretch.None;

viewBox3.Stretch = Stretch.None;


}


ViewBox Demo 2

Picture: ViewBox Demo 2

 

3. Uniform:
If you set the Stretch property to Uniform, the content will resize to fit the ViewBox. The ViewBox will take as much space as require to show the entire content and also preserves the aspect ratio.

<Viewbox Stretch=”Fill” MaxWidth=”100″ MaxHeight=”100″ Name=”viewBox1″>

<Image Source=”images/microsoft_silverlight.jpg”/>

</Viewbox>

<Viewbox Stretch=”Fill”MaxWidth=”200″ MaxHeight=”200″ Name=”viewBox2″>

<Image Source=”images/microsoft_silverlight.jpg”/>

</Viewbox>

<Viewbox Stretch=”Fill”MaxWidth=”300″ MaxHeight=”300″ Name=”viewBox3″>

<Image Source=”images/microsoft_silverlight.jpg”/>

</Viewbox>

//Set the Stretch property to Uniform

privatevoid stretchNone(object sender, RoutedEventArgs e)


{


viewBox1.Stretch = Stretch.Uniform;

viewBox2.Stretch = Stretch.Uniform;

viewBox3.Stretch = Stretch.Uniform;


}


ViewBox Demo 3

Picture: ViewBox Demo 3

 

4. UniformToFill:
If you set the Stretch property to UniformToFill, the content will resize to fill the destination dimension. If the original size differs than the aspect ratio of the ViewBox, the content is then clipped to fit the ViewBox dimension.

<Viewbox Stretch=”Fill” MaxWidth=”100″ MaxHeight=”100″ Name=”viewBox1″>

<Image Source=”images/microsoft_silverlight.jpg”/>

</Viewbox>

<Viewbox Stretch=”Fill”MaxWidth=”200″ MaxHeight=”200″ Name=”viewBox2″>

<Image Source=”images/microsoft_silverlight.jpg”/>

</Viewbox>

<Viewbox Stretch=”Fill”MaxWidth=”300″ MaxHeight=”300″ Name=”viewBox3″>

<Image Source=”images/microsoft_silverlight.jpg”/>

</Viewbox>

//Set the Stretch property to UniformToFill

privatevoid stretchNone(object sender, RoutedEventArgs e)


{


viewBox1.Stretch = Stretch.UniformToFill;

viewBox2.Stretch = Stretch.UniformToFill;

viewBox3.Stretch = Stretch.UniformToFill;


}


ViewBox Demo 4

Picture: ViewBox Demo 4

Introduction to Silverlight Application Development – Silverlight tutorial Chapter 2


In this chapter we will first discuss on how to create a new Silverlight project and the structure of ait. Later in this chapter we will discuss on UserControls and various ways of developement. After reading this chapter you will be able to create a HelloSilverlight application and various UserControls for your application.

Please go to previous chapter to read Introduction to Silverlight.

How to create a new Silverlight Project?

If your development environment is ready then we can proceed towards creating a new Silverlight Application project. At the end of this part we will be able to run our first Silverlight application inside the browser.

1. Open your Visual Studio 2010 IDE

2. Select File > New Project or just press CTRL + SHIFT + N to open up the New Project dialog

3. Expand the “Visual C#” node and then go to sub node “Silverlight”

4. Select “Silverlight Application” in the right pane

 

Create new project

Figure 1: Visual Studio Project Types

 

5. Select proper location to store your application (let’s say, “D:\Sample Apps\”

6. Now enter a proper name for your project (call it as: SilverlightApps.HelloSilverlight)

7. Select the .Net Framework version from the combo box at the top (I am using .Net Framework 4.0 by default as I am using Visual Studio 2010) and click OK

8. In the next dialog make sure that “Host the Silverlight application in a new Web site” option is selected

 

create new silverlight application

Figure 2: Silverlight Hosting Application

 

9. Choose “Silverlight 4” as the Silverlight Version and hit OK

 

Wait for a while, Visual Studio will now create the first Silverlight solution for you to use which will contain a Silverlight Project and one Web Application Project to host your Silverlight application. Once done, you will see Visual Studio already created two XAML files (App.xaml & MainPage.xaml) for you inside the Silverlight Application project.

So for now your first Silverlight application has been created. Press F5 to run the application. It will open a browser Window with a blank page on that. Wow! What happened? Nothing is there!!! Don’t worry, everything is fine. We didn’t modify the default blank XAML page. Just right click on the browser page & you will see the Silverlight context menu on that.

 

first silverlight page

Figure 3: Silverlight inside the Browser

 

 

What’s the Project Structure of Silverlight?

When you create a new Silverlight project, Visual Studio IDE creates two different projects for you (as you can see in the below picture). One is your main Silverlight project and the another is a Web application project which will host your Silverlight application (.xap file).

 

Silverlight project structure

Figure 4: Silverlight Project Structure

 

The main Silverlight project (SilverlightApps.HelloSilverlight) consists of App.xaml, App.xaml.cs, MainPage.xaml & MainPage.xaml.cs. I already discussed on those file in depth in previous chapter. The web project (SilverlightApps.HelloSilverlight.Web) consists of JavaScript file named Silverlight.js which is responsible for checking the Silverlight version in client side and also if the Silverlight plug-in is missing at the user end, it asks to install the required runtime from Microsoft site. The .aspx & .html pages are present in the root to host the Silverlight application. Your Silverlight application .xap file is located under the ClientBin directory inside the Web project.

 

 

Creating a “HelloSilverlight” Application

Now let us start modifying the “MainPage.xaml” by insertinga text “Hello Silverlight”. We will add one TextBlock control inside the Grid panel with it’s text property as “Hello Silverlight”.

But before going to add the content inside your page let me tell you that, you can add it in two ways: “Declarative approach in XAML” and “Programmatic approach in Code-Behind”. In declarative approach you have to add the Silverlight controls in the XAML page in XML format only with their properties as attributes. In other hand, you have to create the objects of the controls programmatically and have to set their properties.

First go with the Declarative Approach:

1. Open the file “MainPage.xaml” in Visual Studio
2. Inside the Grid tag add the following texts:

<TextBlock x:Name=”txtTitle” Text=”Hello Silverlight From XAML” FontSize=”32″ Foreground=”Red” HorizontalAlignment=”Center”/>

Your XAML page will now look like this:

<UserControl x:Class=”SilverlightApps.HelloSilverlight.MainPage”

xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;

xmlns:d=”http://schemas.microsoft.com/expression/blend/2008&#8243;

xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006&#8243;

mc:Ignorable=”d”

d:DesignHeight=”300″ d:DesignWidth=”400″>

<Grid x:Name=”LayoutRoot” Background=”White”>

<TextBlock x:Name=”txtTitle” Text=”Hello Silverlight From XAML”

FontSize=”32″ Foreground=”Red” HorizontalAlignment=”Center”/>

</Grid>

</UserControl>

 

3. Press F5 to run your application once again. Once the browser loads your Silverlight application you will see “Hello SilverlightFrom XAML” text appears inside the browser window.

 

First silverlight application

Figure 5: Hello Silverlight from XAML in Browser

Now, we will create the same from the code behind (programmatically). Assume that, we have not added the Text inside the XAML.

1. Open your “MainPage.xaml.cs” using the Visual Studio
2. There you will find the constructor of the MainPage class. Add the following lines of code after the call to the InitializeComponent() method:


// Create the instance of the textblock and set it’s properties


TextBlock txtTitle = newTextBlock

{

Name = “txtTitle”,

Text = “Hello Silverlight From Code”,

FontSize = 32.0,

Foreground = newSolidColorBrush(Colors.Red),

HorizontalAlignment = HorizontalAlignment.Center

};

// Add the textblock instance as the children of the “LayoutRoot”


LayoutRoot.Children.Add(txtTitle);


Let’s describe it in depth. First of all we are creating the instance of the TextBlock control and setting the Name, Text, FontSize, Foreground color etc. at the time of initialization. Then once the control is ready, we are adding it to the main panel i.e. the Grid layout panel inside the XAML named “LayoutRoot”.

After adding this your code will look like below:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

namespace SilverlightApps.HelloSilverlight


{


publicpartialclassMainPage : UserControl

{

public MainPage()

{

InitializeComponent();

// Create the instance of the textblock and set it’s properties

TextBlock txtTitle = newTextBlock

{

Name = “txtTitle”,

Text = “Hello Silverlight From Code”,

FontSize = 32.0,

Foreground = newSolidColorBrush(Colors.Red),

HorizontalAlignment = HorizontalAlignment.Center

};

// Add the textblock instance as the children of the “LayoutRoot”

LayoutRoot.Children.Add(txtTitle);

}

}


}


3. Press F5 to run your application. You will now see your browser window opens with a text “Hello Silverlight From Code” inside it.

 

Hello Silverlight from Code in Browser

Figure 6: Hello Silverlight from Code in Browser

Note that, the TextBlock control has been added as a child element to the LayoutRoot panel which is a Grid. So, the question here is, what are the panels available in Silverlight where we can add child controls? Ok, for now just remember that there are several content holders (panels) available to hold any child controls like: Grid, Canvas, Border, StackPanel etc. In XAML pages the elements are maintained in a hierarchy like the HTML pages (DOM i.e. Document Object Model). This hierarchy allows us to nest different controls inside each other. I will discuss on this in depth in the next chapter.

Creating a Silverlight UserControl

In our last example we have seen, once we created the Silverlight project, the Visual Studio IDE has automatically created two XAML pages: App.xaml&MainPage.xaml. If you view the MainPage.xaml in depth, you will notice that it started with “UserControl” as the root element.

<UserControl x:Class=”SilverlightApps.HelloSilverlight.MainPage”

. . .>

</UserControl>

Also, if you open the MainPage.xaml.cs file you will notice that the class itself inherits from the base class “UserControl”.

namespace SilverlightApps.HelloSilverlight


{


publicpartialclassMainPage : UserControl

{

public MainPage()

{

InitializeComponent();

}

}


}


 

 

So, what is that UserControl? UserControls are basic unit of reusable XAML like you use in asp.net. It is the root of your XAML and contain only one child as a control. Though that child may contain one or more other controls but the UserControl must have a maximum of one content control. UserControls are mainly created using XAML and then reused in various places.

How can I create a simple new Silverlight UserControl? Is it difficult to implement? Ummm… I will not tell you. Let us create a simple UserControl then. You will tell me whether it is difficult or simple.

 
Silverlight Tools for Visual Studio comes up with the default template for creating a basic UserControl. Now follow the steps to create it:

  1. Open your existing Silverlight application project (for this example, you can use the “HelloSilverlight” project just now we created)
  2. Right click on the Silverlight project “SilverlightApps.HelloSilverlight” and select Add -> New Item
  3. Select “Silverlight UserControl” from the right panel
  4. Enter a good name (here I am using “EmployeeView”) and hit enter

Silverlight UserControl Creation

Figure 7: Silverlight UserControl Creation

 

This will create the UserControl named “EmployeeView” with the default template layout and open up the XAML page in the IDE. If you look into the XAML code you will notice the following code:

 

<UserControl x:Class=”SilverlightApps.HelloSilverlight.EmployeeView”

xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;

xmlns:d=”http://schemas.microsoft.com/expression/blend/2008&#8243;

xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006&#8243;

mc:Ignorable=”d”

d:DesignHeight=”300″ d:DesignWidth=”400″>

<Grid x:Name=”LayoutRoot” Background=”White”>

</Grid>

</UserControl>

 

We already discussed about each of the lines in the previous chapter (in “What is MainPage.xaml file” section). So, I will not cover it again. Now let us build our first UserControl to show the Employee’s FirstName, LastName& Department inside the UserControl XAML file. How to do that? Before doing it let us split our Grid panel into three Rows & two Columns (will discuss on this in next chapter):

 

<Grid x:Name=”LayoutRoot” Background=”White”>

<Grid.RowDefinitions>

<RowDefinition/>

<RowDefinition/>

<RowDefinition/>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<ColumnDefinition Width=”100″/>

<ColumnDefinition Width=”*”/>

</Grid.ColumnDefinitions>

</Grid>

 

Now, lets add the TextBlocks inside the Grid, in specific Rows and Columns. In our case the left column will hold the “FirstName”, “LastName” and “Department” label. The second column will hold the informations according to the labels. Here is the XAML code for the same:

 

<UserControl x:Class=”SilverlightApps.HelloSilverlight.EmployeeView”

xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;

xmlns:d=”http://schemas.microsoft.com/expression/blend/2008&#8243;

xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006&#8243;

mc:Ignorable=”d” Width=”300″>

<Grid x:Name=”LayoutRoot” Background=”White”>

<Grid.RowDefinitions>

<RowDefinition/>

<RowDefinition/>

<RowDefinition/>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<ColumnDefinition Width=”100″/>

<ColumnDefinition Width=”*”/>

</Grid.ColumnDefinitions>

<TextBlock x:Name=”LabelFirstName” Text=”FirstName” Grid.Row=”0″ Grid.Column=”0″/>

<TextBlock x:Name=”FirstName” Text=”Kunal” Grid.Row=”0″ Grid.Column=”1″/>

<TextBlock x:Name=”LabelLastName” Text=”LastName” Grid.Row=”1″ Grid.Column=”0″/>

<TextBlock x:Name=”LastName” Text=”Chowdhury” Grid.Row=”1″ Grid.Column=”1″/>

<TextBlock x:Name=”LabelDepartment” Text=”Department” Grid.Row=”2″ Grid.Column=”0″/>

<TextBlock x:Name=”Department” Text=”Software Engineering” Grid.Row=”2″ Grid.Column=”1″/>

</Grid>

</UserControl>

 

You can see, I am using “Grid.Row” and “Grid.Column” attributes in each TextBlock. What does it mean? Grid.Row specifies the row number where to place the control. Similarly, Grid.Column specifies the column number. For example, if you use Grid.Row=”2” and Grid.Column=”4” to any element inside your Grid, the element control will be placed in 3rd Row and 5th Column of the Grid. You can think the Grid panel as a Matrix which has zero based index.

Our UserControl is ready now, but before running the application we need to put it inside the MainPage which loads at application load. You can do this in two different ways. One is using the XAML and the another is using the Code-behind file. In code behind it is very easy. You have to follow the same steps as we did in previous chapter to set the “Hello Silverlight” TextBlock, but if you want to set it in XAML you have to do a little trick for the first time. Let us discuss on this step-by-step:

 

First go with the Declarative Approach:

1. Open the file “MainPage.xaml” in Visual Studio
2. Add the following line inside the UserControl tag of the MainPage.xaml (after any xmlns line):

xmlns:uc="clr-namespace:SilverlightApps.HelloSilverlight"

Now, your MainPage.xaml will look like this (the bolder text I have inserted in the XAML):

<UserControl x:Class=”SilverlightApps.HelloSilverlight.MainPage”

xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;

xmlns:d=”http://schemas.microsoft.com/expression/blend/2008&#8243;

xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006&#8243;

xmlns:uc=”clr-namespace:SilverlightApps.HelloSilverlight”

mc:Ignorable=”d”

d:DesignHeight=”300″ d:DesignWidth=”400″>

<Grid x:Name=”LayoutRoot” Background=”White”>

</Grid>

</UserControl>

 

Here, “uc” stands for pre-tag for specifying the namespace. You can use any name. We used “uc” to specify “UserControl” for better readability. Now inside the Grid control you can add the UserControl we have just created. Here is the code for the same:

 

<Grid x:Name=”LayoutRoot” Background=”White”>

<uc:EmployeeView Width=”300″ Height=”60″/>

</Grid>

Once you run your application now, you will see the following view of your first UserControl application:

First UserControl View

Figure 8: First UserControl View

 

Now let us create it from Code-behind. I assume that the control we just added inside the Grid has been removed from the XAML, that means your Grid panel has no child inside it. Create the instance of the EmployeeViewUserControl and add it as child to the LayoutRoot Grid:


// Create the instance of the EmployeeViewUserControl


EmployeeView empView = new EmployeeView


{


Width = 300.0,

Height = 60.0,


};


// Add the EmployeeViewUserControl as the child of the default panel “LayoutRoot”


LayoutRoot.Children.Add(empView);

 

Run your application and you will see the same output. The second approach is easy, am I right? Yup, for the first application it looks very easy enough. But when you write complex applications you will notice that the first approach is easier than the later. Why? Because, you will get more control over the design. You can see the output immediately in the preview sceen, also you can drag the control to position it properly in the panel. In some cases you will find it useful from code.  Depending upon your business need you have to decide where to create and add your UserControl.

Is it confusing? No, when you are sure that you have to dynamically load no. of UserControls based on your data you have to create and load it from the code behind. For the other cases, it will be easier to write inside the XAML.

Remember that, you can create as many instances of your UserControl and place it inside your XAML page. Once we discuss on the different types of panel and layout in next chapter you can get better visibility to that.

How to Start with Silverlight


As we all know that Microsoft Silverlight is a cross-browser, cross-platform, and cross-device plug-in for delivering the next generation of .NET based media experiences and rich interactive applications for the Web. In order to work with Silverlight first you need to install the Silverlight plug-in. Please install the from Silverlight plug-in. To add Silverlight to your file, you need a reference to the Silverlight.js file into your, a xaml file that contains the behavior of the Silverlight and some JavaScript code to creates Silverlight plug-in instance.

Step – 1
If you are going to use Silverlight into your ASP.NET website, you need to add the reference of Silverlight.js file into your page (If you have master page, better to add the reference into it so that you don’t need to add the reference to all your .aspx pages). Please note that the referecne of Silverlight should be placed between <head> and </head> tag and your code should look like <script src=”Silverlight.js” type=”text/javascript”></script>. Silverlight.js file can be found at this website too, however we suggest to get the latest from Microsoft website.
Get Microsoft Silverlight
Step – 2
You need to create a placeholder for your Silverlight content inside your <body> </body> tag where you want your Silverlight content to appear. In general, you should create a div html element and specify its id property like this <div id=”fundaSilverlightPluginHost”> </div>

Step – 3
Write the JavaScript code to call the initialization function of Silverlight object like this. You can write this code after your placeholder (Step-2).

                    <script language="javascript" type="text/javascript">
                        createSilverlightPlugin('fundaSilverlightPluginHost', '300', '200', 'YourXamlFilePath.xaml')
                    </script>

Here I am passing all the required value as a parameter. In this case the
1st parameter is the placeholder that I created in the 2nd step,
2nd parameter is the width of the Silverlight plug-in area
3rd parameter is the height of the Silverlight plug-in area
4thparameter is the .xaml file that specifies the behavior of the Silverlight objectStep – 4
Write JavaScript function to initialize the Silverlight object. In my case it looks like below. It can be placed inside the common JavaScript file of your website. In any case, this code must be rendered to the browse before last step (Step – 3) code otherwise browser may throw JavaScript error. Its always better to place this code between <head> and </head>.

                    
function createSilverlightPlugin(placeHolder, width, height, xamlfile)
{  
    // Retrieve the div element you created in the previous step.
    var parentElement = document.getElementById(placeHolder);
    Silverlight.createObject
    (
        xamlfile,                       // Source property value.
        parentElement,                  // DOM reference to hosting DIV tag.
        placeHolder,                    // Unique plug-in ID value.
        {                               // Per-instance properties.
            width:width,                // Width of rectangular region of 
                                        // plug-in area in pixels.
            height:height,              // Height of rectangular region of 
                                        // plug-in area in pixels.
            inplaceInstallPrompt:false, // Determines whether to display 
                                        // in-place install prompt if 
                                        // invalid version detected.
            background:'#fecefe',       // Background color of plug-in.
            isWindowless:'false',       // Determines whether to display plug-in 
                                        // in Windowless mode.
            framerate:'24',             // MaxFrameRate property value.
            version:'1.0'               // Silverlight version to use.
        },
        {
            onError:null,               // OnError property value -- 
                                        // event handler function name.
            onLoad:null                 // OnLoad property value -- 
                                        // event handler function name.
        },
        null
    );                                  // Context value -- event handler function name.
}

Step – 5
Now, you have the placehoder object and function to initialize the Silverlight object. Its time to write the behavior of the Silverlight object. So create a .xaml file and write below code. Please note that you need to specify this file path as a 4thparameter of Step – 3 initialization function.

<Canvas
   xmlns="http://schemas.microsoft.com/client/2007"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Rectangle Height="75" Width="200" Fill="LightGreen" Stroke="Red" StrokeThickness="2" Canvas.Left="5" Canvas.Top="5"></Rectangle>
  <TextBlock Canvas.Left="85" Canvas.Top="20" FontSize="15" FontFamily="Arial, Verdana" Text="DotNetFunda.com Silverlight Tutorials"
               FontWeight="Bold" Foreground="Blue" TextWrapping="Wrap"></TextBlock>

</Canvas>

Instead of writing above code into a separate .xaml file, you may write it into your .aspx page as well. In that case your code should look like below.

  <script type="text/xml" id="xamlScript2">
  <?xml version="1.0"?>
  <Canvas 
    xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Rectangle Height="75" Width="400" Fill="Blue" Stroke="Red" 
        StrokeThickness="2" Canvas.Left="5" Canvas.Top="5"></Rectangle>
          <TextBlock Canvas.Left="20" Canvas.Top="30" FontSize="20" 
          FontFamily="Arial, Verdana" Text="DotNetFunda.com Silverlight Tutorials"
                       FontWeight="Bold" Foreground="White" TextWrapping="Wrap"></TextBlock>
  </Canvas>
</script>

Notice that if you have written the .xaml code into your .aspx page, your Step – 3 code should be slightly changed as below. Here, instead of specifying the .xaml file path in the 4th parameter of initialization function, you need to specify the id of the .xaml code preceeded by #.

                    <script language="javascript" type="text/javascript">
                        createSilverlightPlugin('divDemoSliverlight', '450', '100', '#xamlScript2')
                    </script>

Step – 6
Thats it!, Just run your page in the browser and you should see a Silverlight banner like below.

Get Microsoft Silverlight

Acknowledgement: I have taken reference of Silverlight.net website in writing these articles.

Simple Silverlight 4 Example Using oData and RX Extensions


Introduction

This is part II to the previous clog (http://openlightgroup.net/Blog/tabid/58/EntryId/98/OData-Simplified.aspx) where we looked at a simple ODataexample. This time, we will make a simple Silverlight application that talks to an oData service.

Note, for this tutorial, you will also need to download and install RX Extensions from: http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx, and the Silverlight Toolkit from: http://silverlight.codeplex.com.

As with the last tutorial, we will not use a database, just a simple collection that we are creating programmatically. This will allow you to see just the oData parts.

First, open up the project, in Visual Studio 2010 (or higher), from the zip file at the bottom of this link.

Select Add, then New Project…

Create a new Silverlight Application.

Add a Service Reference.

Click Discover.

Create a reference called wsSampleCustomerData.

Next, add assembly references in your Silverlight project to:

  • System.CoreEx
  • System.Observable
  • System.Reactive

In the Silverlight project, delete the MainPage.xaml.

Open the project in Expression Blend 4 (or higher).

In Expression Blend, select File then New Item…

Select the UserControl with ViewModel template, and create a file called MainPage.xaml.

It will create the ViewModel pages (MainPage.xaml and MainPage.xaml.cs with a MainPageModel.cs View Model page that is already wired-up).

Create a folder called Model and a class called Model.cs.

Replace all the code with the following code:

 Collapse
using System;
using System.Linq;
using System.Collections.Generic;
using SilverlightODataSample.wsSampleCustomerData;
using System.Data.Services.Client;

namespace SilverlightODataSample
{
    public class Model
    {
        #region GetCustomers
        public static IObservable < IEvent < LoadCompletedEventArgs> > 
            GetCustomers(int intPage)
        {
            // Create a URI that points to the OData Service
            Uri objUri = new Uri(GetBaseAddress(), UriKind.RelativeOrAbsolute);

            // Set up oData service call
            SampleDataSource SDS = new SampleDataSource(objUri);

            // Construct a Query
            var query = (from SampleCustomerData in SDS.SampleCustomerData
                         where SampleCustomerData.CustomerNotes.Contains("3")
                         select SampleCustomerData).Skip(intPage).Take(10);

            // Set up a DataServiceCollection to hold the results
            DataServiceCollection< CustomerRecord > CustomerRecords = 
                new DataServiceCollection< CustomerRecord >();

            // Set up a Rx Observable (in a variable called observable) 
            // that will contain the results of
            // the "LoadCompleted" event that CustomerRecords will fire
            // When LoadAsync(query) is fired in the following statement
            IObservable< IEvent < LoadCompletedEventArgs> > observable =
                Observable.FromEvent< LoadCompletedEventArgs >(CustomerRecords,
                "LoadCompleted");

            // Execute the LoadAsync on CustomerRecords passing
            // the query that was constructed earlier
            CustomerRecords.LoadAsync(query);

            // Return observable
            return observable;
        }
        #endregion

        #region GetBaseAddress
        private static string GetBaseAddress()
        {
            // This gets the address of the webservice by 
            // getting the AbsoluteUri and then stripping out the 
            // name of the .xap file
            string strXapFile = @"/ClientBin/SilverlightODataSample.xap";
            string strBaseWebAddress =
                App.Current.Host.Source.AbsoluteUri.Replace(strXapFile, "");
            return string.Format(@"{0}/{1}", strBaseWebAddress, @"Service.svc");
        }
        #endregion
    }
}

Open MainPageModel.cs and replace all the code with the following code:

 Collapse
using System;
using System.ComponentModel;
using System.Collections.ObjectModel;
using SilverlightODataSample.wsSampleCustomerData;
using System.Data.Services.Client;

namespace SilverlightODataSample
{
    public class MainPageModel : INotifyPropertyChanged
    {
        public MainPageModel()
        {
            // When the Control loads
            // Get the Customers
            GetCustomers();
        }

        #region GetCustomers
        private void GetCustomers()
        {
            // Call the Model to get the Customers
            // Passing in 0 to get the first page
            // Paging could easily be done here
            // You could also pass in other criteria
            Model.GetCustomers(0).Subscribe(p = >
            {
                // Check for an error in the Service
                if (p.EventArgs.Error == null)
                {
                    // loop thru each item in the
                    // DataServiceCollection< CustomerRecord >
                    // Collection
                    foreach (CustomerRecord Customer in
                        (DataServiceCollection< CustomerRecord >)p.Sender)
                    {
                        // Add to the Customer to the colCustomerRecord 
                        // Collection so the View can bind to it
                        colCustomerRecord.Add(Customer);
                    }
                }
            });

        }
        #endregion

        #region CustomerRecord
        // The View will bind to this collection and automatically be notified if 
        // The collection changes. The Designer can bind any UI element that 
        // can hold a collection
        private ObservableCollection< CustomerRecord > _colCustomerRecord
            = new ObservableCollection< CustomerRecord >();
        public ObservableCollection< CustomerRecord > colCustomerRecord
        {
            get { return _colCustomerRecord; }
            private set
            {
                if (colCustomerRecord == value)
                {
                    return;
                }

                _colCustomerRecord = value;
                this.NotifyPropertyChanged("colCustomerRecord");
            }
        }
        #endregion

        #region INotifyPropertyChanged
        // This is a supporting method to raise a notification for any
        // Element that is subscribed to a Property that implements
        // NotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        #endregion
    }
}

Grab a DataGrid and drop it on the design surface.

Widen it so it fills the page.

Click on the Data tab so that you see the Data Context.

Drag and drop the colCustomerRecord collection onto the DataGrid.

Build and run the project.

OData and RX extensions are pretty impressive:

  • RX extensions were used because it decouples the oData Service calls from the View Model. This allows the methods in the model to be easily called by multiple View Models.
  • We are only grabbing the first page of the results, but we could easily implement paging by passing the page number to the method.
  • We are also only creating a simple query. We could easily create a more complex query of the oData Service.

RIATasks: A Simple Silverlight CRUD Example (using View Model)


A Simple Silverlight CRUD Example

Live example: http://silverlight.adefwebserver.com/RIATasks/

Also see: Silverlight RIA Tasks 2: Dynamic View Models

img32.jpg

The reason for this tutorial, is that I have noticed my friends are getting stuck when trying to learn Silverlight. They spend a lot of time “learning about Silverlight” but have a hard time actually getting started.

I also wanted to show them how to use View Model Style programming because I believe that using View Model, you will write LESS CODE (you probably didn’t expect that one!). Don’t believe me? Let me show you…

Silverlight is different because it communicates with the website that launches it using asynchronous communication. Learning how to design applications this way can be a bit challenging.

So I created an end-to-end example, that achieves these goals:

  • Creates, Reads, Updates, and Deletes records from the database
  • Implements Forms based security
  • Implements “Granular Security” (“only allow User One to see, edit, and create their own Tasks“)
  • Implements View Model Style

View Model Style

View Model Style allows a programmer to create an application that has absolutely no UI (user interface). The programmer only creates a View Modeland a Model. A designer with no programming ability at all, is then able to start with a blank page and completely create the View (UI) in Microsoft Expression Blend 4 (or higher). If you are new to View Model Style it is suggested that you read Silverlight View Model Style : An (Overly) Simplified Explanation for an introduction.

The Application

First, let’s look at the sample application.

When you first start the application, you are “Logged Out”. You can use the drop down to log in as User One or User Two.

Click the Add button to add a new Task.

Clicking the Update button will save the Task.

  • Clicking on the Task in the list box will display the Task.
  • Clicking the Update button will save any changes
  • Clicking the Delete button will delete the Task.

Create The Application

We will now create the Application. You will need:

  • Visual Studio 2010 (or higher)
  • Expression Blend 4 (or higher)
  • SQL Server (2005 or higher)

Setting Up The Database

Create a new database called RIATasks

Create a table called Tasks, using the following script:

 Collapse
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Tasks]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[Tasks](
    [TaskID] [int] IDENTITY(1,1) NOT NULL,
    [TaskName] [nvarchar](50) NOT NULL,
    [TaskDescription] [nvarchar](max) NOT NULL,
    [UserID] [int] NOT NULL,
 CONSTRAINT [PK_Tasks] PRIMARY KEY CLUSTERED 
(
    [TaskID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
END
GO
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[Tasks]') AND name = N'IX_Tasks_UserID')
CREATE NONCLUSTERED INDEX [IX_Tasks_UserID] ON [dbo].[Tasks] 
(
    [UserID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, 
DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

You will also need to set security so that you will be able to connect to the database in the next step.

(If SQL server is too hard for you to set it up, you can cover similar material in: Silverlight View Model Style File Manager and View Model Style: Silverlight Video Player)

Create The Web Application Project

Open Visual Studio and select File then New Project…

Create a Silverlight Application project.

Accept the defaults and click OK.

The project will be created.

Enable Forms Authentication

We need to set-up the web application to use Forms Authentication. When the user logs in, they will create an encrypted authentication ‘token’ in their web browser, that contains their UserID. This ‘token’ will be used by the Silverlight application when making web service calls. The web service methods (created in a later step) will check this ‘token’ to enforce security.

Open the Web.config file.

Add <authentication mode=”Forms”/> to the file. Then save and close it.

Create Default Page

Create a Web Form page called Default.aspx in the RIATasks.Web project.

Open the RIATasksTestPage.aspx page and switch to Source view.

Copy everything from <!DOCTYPE to the end of the page…

… and paste it in the source for the Default.aspx page, replacing everything from <!DOCTYPE to the end of the page.

We need to convert the Div tag the Silverlight control is in, to a Panel control so that it can be programmatically hidden if the user is not logged in.

  • Replace: <div id=”silverlightControlHost”>
    • With: <asp:panel id=”silverlightControlHost” runat=”server”>
  • Replace: </div>
    • With: </asp:panel>

Now, we need to add a drop-down so a user can log in (in a real application you would use a normal Login Form).

Insert the following code in the page under the Form tag:

 Collapse
<asp:DropDownList ID="ddlUser" runat="server" AutoPostBack="True" 
onselectedindexchanged="ddlUser_SelectedIndexChanged">
<asp:ListItem Selected="True" Value="0">Logged Out</asp:ListItem>
<asp:ListItem Value="1">User One</asp:ListItem>
<asp:ListItem Value="2">User Two</asp:ListItem>
</asp:DropDownList>

Open the Default.aspx.cs file and replace ALL the code with the following code:

 Collapse
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;

namespace RIATasks.Web
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                LogOut();
            }
        }

        #region ddlUser_SelectedIndexChanged
        protected void ddlUser_SelectedIndexChanged(object sender, EventArgs e)
        {
            int intSelectedUser = Convert.ToInt32(ddlUser.SelectedValue);
            if (intSelectedUser > 0)
            {
                LogUserIntoSite(Convert.ToInt32(ddlUser.SelectedValue));
            }
            else
            {
                LogOut();
            }
        }
        #endregion

        #region LogUserIn
        private void LogUserIntoSite(int intUser)
        {
            // Log the user into the site
            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
              intUser.ToString(),
              DateTime.Now,
              DateTime.Now.AddDays(30),
              false,
              "Role One",
              FormsAuthentication.FormsCookiePath);

            // Encrypt the ticket.
            string encTicket = FormsAuthentication.Encrypt(ticket);

            // Create the cookie.
            Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));

            // Show the Silverlight control
            silverlightControlHost.Visible = true;
        }
        #endregion

        #region LogOut
        protected void LogOut()
        {
            FormsAuthentication.SignOut();

            // Hide the Silverlight control
            silverlightControlHost.Visible = false;
        }
        #endregion
    }
}

Right-click on the Default.aspx page and select Set As Start Page…

Hit F5 to run the project.

The project will run and open in the web browser.

You will be able to change the drop down to log in as a user.

Close the web browser.

Create the Data Layer

Add a Linq to SQL class to the RIATaks.Web site called RIATasksDB.dbml.

Note: You could use Entity Framework instead of Linq to SQL (or any other data access technology). We use Linq to SQL only because it is easier to set-up.

Select the Server Explorer.

Create a connection to the RIATasks database, and drag the Tasks table to the Object Relational Designer surface.

The data layer is complete.

Save and close the file.

Create The Web Service

Add a Web Service file to the RIATaks.Web site called Webservice.asmx.

Open the WebService.asmx.cs file that is created and replace ALL the code with the following code:

 Collapse
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace RIATasks.Web
{
    [WebService(Namespace = "http://OpenLightGroup.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    public class WebService : System.Web.Services.WebService
    {
        #region GetCurrentUserID
        private int GetCurrentUserID()
        {
            int intUserID = -1;
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                // Get the current user
                intUserID = Convert.ToInt32(HttpContext.Current.User.Identity.Name);
            }
            return intUserID;
        }
        #endregion

        // Web Methods

        #region GetTasks
        [WebMethod]
        public List<Task> GetTasks()
        {
            // Create a collection to hold the results
            List<Task> colResult = new List<Task>();

            RIATasksDBDataContext DB = new RIATasksDBDataContext();

            var colTasks = from Tasks in DB.Tasks
                           where Tasks.UserID == GetCurrentUserID()
                           select Tasks;

            // Loop thru the Tasks
            foreach (var item in colTasks)
            {
                // Create a Task
                Task tmpTask = new Task();

                // Set only the TaskID and the Name
                // We do this because Description could be 
                // a large amount of data that will slow down
                // the application and we don't need it now
                tmpTask.TaskID = item.TaskID;
                tmpTask.TaskName = item.TaskName;

                // Add to the final results
                colResult.Add(tmpTask);
            }

            return colResult;
        }
        #endregion

        #region GetTask
        [WebMethod]
        public Task GetTask(int TaskID)
        {
            RIATasksDBDataContext DB = new RIATasksDBDataContext();

            var result = (from Tasks in DB.Tasks
                          where Tasks.TaskID == TaskID
                          where Tasks.UserID == GetCurrentUserID()
                          select Tasks).FirstOrDefault();

            return result;
        }
        #endregion

        #region DeleteTask
        [WebMethod]
        public string DeleteTask(int TaskID)
        {
            string strError = "";
            RIATasksDBDataContext DB = new RIATasksDBDataContext();

            try
            {
                var result = (from Tasks in DB.Tasks
                              where Tasks.TaskID == TaskID
                              where Tasks.UserID == GetCurrentUserID()
                              select Tasks).FirstOrDefault();

                if (result != null)
                {
                    DB.Tasks.DeleteOnSubmit(result);
                    DB.SubmitChanges();
                }
            }
            catch (Exception ex)
            {
                strError = ex.Message;
            }

            return strError;
        }
        #endregion

        #region UpdateTask
        [WebMethod]
        public string UpdateTask(Task objTask)
        {
            string strError = "";
            RIATasksDBDataContext DB = new RIATasksDBDataContext();

            try
            {
                var result = (from Tasks in DB.Tasks
                              where Tasks.TaskID == objTask.TaskID
                              where Tasks.UserID == GetCurrentUserID()
                              select Tasks).FirstOrDefault();

                if (result != null)
                {
                    result.TaskDescription = objTask.TaskDescription;
                    result.TaskName = objTask.TaskName;

                    DB.SubmitChanges();
                }
            }
            catch (Exception ex)
            {
                strError = ex.Message;
            }

            return strError;
        }
        #endregion

        #region InsertTask
        [WebMethod]
        public Task InsertTask(Task objTask)
        {
            RIATasksDBDataContext DB = new RIATasksDBDataContext();

            try
            {
                Task InsertTask = new Task();

                InsertTask.TaskDescription = objTask.TaskDescription;
                InsertTask.TaskName = objTask.TaskName;
                InsertTask.UserID = GetCurrentUserID();

                DB.Tasks.InsertOnSubmit(InsertTask);
                DB.SubmitChanges();

                // Set the TaskID 
                objTask.TaskID = InsertTask.TaskID;
            }
            catch (Exception ex)
            {
                // Log the error
                objTask.TaskID = -1;
                objTask.TaskDescription = ex.Message;
            }

            return objTask;
        }
        #endregion
    }
}

Note that the web service methods call GetCurrentUserID(), that uses Convert.ToInt32(HttpContext.Current.User.Identity.Name), to get the current user.

The current UserID is set when the user logs in and creates a authentication “token“. The user’s web browser passes this token on all requests, including the web service requests that will be made by the Silverlight application.

To check that everything is set up correctly, you can right-click on the WebService.asmx file, and select View in Browser.

The web methods will display.

Note: You could use WCF instead. We use .asmx web services because they are easier to deploy.

The Silverlight Project

We will now complete the RIATasks Silverlight project. first, we need to create a reference, from the Silverlight project, to the web service we just created.

Then, we need to make a Model to call the web service we created, and an ICommand support class, that will allow us to easily raise events in theView Model.

Create the Web Service Reference

In the Silverlight Project, Right-click on References and select Add Service Reference…

  • Click the Discover button
  • Enter wsRIATasks for Namespace
  • Click the OK button

The connection between the Silverlight project and the website is complete. We will implement code, in a later step, that will use this reference to call the web service we created.

Add References

Add a Reference to Microsoft.VisualBasic

ICommand Support Class

Add a new folder and call it Classes. and then right-click on it and select New Item…

Create a class called DelegateCommand.cs.

Replace ALL the code with the following code:

 Collapse
using System.Windows.Input;
using System;

// From http://johnpapa.net/silverlight/5-simple-steps-to-commanding-in-silverlight/
namespace RIATasks
{
    public class DelegateCommand : ICommand
    {
        Func<object, bool> canExecute;
        Action<object> executeAction;
        bool canExecuteCache;

        public DelegateCommand(Action<object> executeAction, Func<object, bool> canExecute)
        {
            this.executeAction = executeAction;
            this.canExecute = canExecute;
        }

        #region ICommand Members

        public bool CanExecute(object parameter)
        {
            bool temp = canExecute(parameter);

            if (canExecuteCache != temp)
            {
                canExecuteCache = temp;
                if (CanExecuteChanged != null)
                {
                    CanExecuteChanged(this, new EventArgs());
                }
            }

            return canExecuteCache;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            executeAction(parameter);
        }

        #endregion
    }
}

This class allows us to easily invoke ICommands. You can get more information on this class at: http://johnpapa.net/silverlight/5-simple-steps-to-commanding-in-silverlight/

The Model

Create a folder called Models, and a class called TasksModel.cs.

Replace all the code with the following code:

 Collapse
using Microsoft.VisualBasic;
using System.Linq;
using System;
using System.Collections.Generic;
using System.ServiceModel;
using RIATasks.wsRIATasks;

namespace RIATasks
{
    public class TasksModel
    {
        #region GetTask
        public static void GetTask(int TaskID, EventHandler<GetTaskCompletedEventArgs> eh)
        {
            // Set up web service call
            WebServiceSoapClient WS = new WebServiceSoapClient();

            // Set the EndpointAddress
            WS.Endpoint.Address = new EndpointAddress(GetBaseAddress());

            WS.GetTaskCompleted += eh;
            WS.GetTaskAsync(TaskID);
        }
        #endregion

        #region GetTasks
        public static void GetTasks(EventHandler<GetTasksCompletedEventArgs> eh)
        {
            // Set up web service call
            WebServiceSoapClient WS = new WebServiceSoapClient();

            // Set the EndpointAddress
            WS.Endpoint.Address = new EndpointAddress(GetBaseAddress());

            WS.GetTasksCompleted += eh;
            WS.GetTasksAsync();
        }
        #endregion

        #region DeleteTask
        public static void DeleteTask(int TaskID, EventHandler<DeleteTaskCompletedEventArgs> eh)
        {
            // Set up web service call
            WebServiceSoapClient WS = new WebServiceSoapClient();

            // Set the EndpointAddress
            WS.Endpoint.Address = new EndpointAddress(GetBaseAddress());

            WS.DeleteTaskCompleted += eh;
            WS.DeleteTaskAsync(TaskID);
        }
        #endregion

        #region UpdateTask
        public static void UpdateTask(Task objTask, EventHandler<UpdateTaskCompletedEventArgs> eh)
        {
            // Set up web service call
            WebServiceSoapClient WS = new WebServiceSoapClient();

            // Set the EndpointAddress
            WS.Endpoint.Address = new EndpointAddress(GetBaseAddress());

            WS.UpdateTaskCompleted += eh;
            WS.UpdateTaskAsync(objTask);
        }
        #endregion

        #region InsertTask
        public static void InsertTask(Task objTask, EventHandler<InsertTaskCompletedEventArgs> eh)
        {
            // Set up web service call
            WebServiceSoapClient WS = new WebServiceSoapClient();

            // Set the EndpointAddress
            WS.Endpoint.Address = new EndpointAddress(GetBaseAddress());

            WS.InsertTaskCompleted += eh;
            WS.InsertTaskAsync(objTask);
        }
        #endregion

        // Utility

        #region GetBaseAddress
        private static Uri GetBaseAddress()
        {
            // Get the web address of the .xap that launched this application     
            string strBaseWebAddress = App.Current.Host.Source.AbsoluteUri;
            // Find the position of the ClientBin directory        
            int PositionOfClientBin =
                App.Current.Host.Source.AbsoluteUri.ToLower().IndexOf(@"/clientbin");
            // Strip off everything after the ClientBin directory         
            strBaseWebAddress = Strings.Left(strBaseWebAddress, PositionOfClientBin);
            // Create a URI
            Uri UriWebService = new Uri(String.Format(@"{0}/WebService.asmx", strBaseWebAddress));
            // Return the base address          
            return UriWebService;
        }
        #endregion
    }
}

Note: GetBaseAddress() is a method that determines where the user launched the .xap (that the Silverlight application is contained in), and uses that to determine where the WebService.asmx file is at. The Web Service methods use that address to call the Web Service.

We have now created methods in the Model that communicate with the methods created in the Web Service created earlier.

Create a folder called ViewModels, and add class called MainPageModel.cs.

Replace all the code with the following code:

 Collapse
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
using System.Windows;
using RIATasks.wsRIATasks;

namespace RIATasks
{
    public class MainPageModel : INotifyPropertyChanged
    {
        public MainPageModel()
        {
            // Set the command property
            GetTasksCommand = new DelegateCommand(GetTasks, CanGetTasks);
            GetTaskCommand = new DelegateCommand(GetTask, CanGetTask);
            DeleteTaskCommand = new DelegateCommand(DeleteTask, CanDeleteTask);
            UpdateTaskCommand = new DelegateCommand(UpdateTask, CanUpdateTask);
            AddNewTaskCommand = new DelegateCommand(AddNewTask, CanAddNewTask);

            // The following line prevents Expression Blend
            // from showing an error when in design mode
            if (!DesignerProperties.IsInDesignTool)
            {
                // Get the Tasks for the current user
                GetTasks();

                // Set Visibility
                HasCurrentTask = Visibility.Collapsed;
                AddVisibility = Visibility.Visible;
                UpdateVisibility = Visibility.Collapsed;
                DeleteVisibility = Visibility.Collapsed;
            }
        }

        // Utility

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        #endregion
    }
}

This code implements INotifyPropertyChanged that will be used by Properties (created in a later step), to automatically notify the View when they have been updated.

The constructor, MainPageModel(), sets up some ICommands (that will be fully implemented in a later step). It also calls the GetTasks(), method, that will call the Model (that will then call the web service), and retrieve any Tasks for the logged in user.

Note: You will see wavy red lines underneath most of the lines in the code because it sets properties and commands that have not been created yet.

Add the following code to the class:

 Collapse
// Properties

        #region CurrentTask
        private Task _CurrentTask = new Task();
        public Task CurrentTask
        {
            get { return _CurrentTask; }
            private set
            {
                if (CurrentTask == value)
                {
                    return;
                }
                _CurrentTask = value;
                this.NotifyPropertyChanged("CurrentTask");
            }
        }
        #endregion

        #region AddVisibility
        private Visibility _AddVisibility = Visibility.Visible;
        public Visibility AddVisibility
        {
            get { return _AddVisibility; }
            private set
            {
                if (AddVisibility == value)
                {
                    return;
                }
                _AddVisibility = value;
                this.NotifyPropertyChanged("AddVisibility");
            }
        }
        #endregion

        #region UpdateVisibility
        private Visibility _UpdateVisibility = Visibility.Visible;
        public Visibility UpdateVisibility
        {
            get { return _UpdateVisibility; }
            private set
            {
                if (UpdateVisibility == value)
                {
                    return;
                }
                _UpdateVisibility = value;
                this.NotifyPropertyChanged("UpdateVisibility");
            }
        }
        #endregion

        #region DeleteVisibility
        private Visibility _DeleteVisibility = Visibility.Visible;
        public Visibility DeleteVisibility
        {
            get { return _DeleteVisibility; }
            private set
            {
                if (DeleteVisibility == value)
                {
                    return;
                }
                _DeleteVisibility = value;
                this.NotifyPropertyChanged("DeleteVisibility");
            }
        }
        #endregion

        #region HasTasks
        private Visibility _HasTasks = Visibility.Collapsed;
        public Visibility HasTasks
        {
            get { return _HasTasks; }
            private set
            {
                if (HasTasks == value)
                {
                    return;
                }
                _HasTasks = value;
                this.NotifyPropertyChanged("HasTasks");
            }
        }
        #endregion

        #region HasCurrentTask
        private Visibility _HasCurrentTask = Visibility.Collapsed;
        public Visibility HasCurrentTask
        {
            get { return _HasCurrentTask; }
            private set
            {
                if (HasCurrentTask == value)
                {
                    return;
                }
                _HasCurrentTask = value;
                this.NotifyPropertyChanged("HasCurrentTask");
            }
        }
        #endregion

        #region Message
        private string _Message;
        public string Message
        {
            get { return _Message; }
            private set
            {
                if (Message == value)
                {
                    return;
                }
                _Message = value;
                this.NotifyPropertyChanged("Message");
            }
        }
        #endregion

This looks like a lot of code, but it is only Properties that will hold values that will be set and consumed by the View. All of them raiseNotifyPropertyChanged when they are changed.

Add the following code to the class:

 Collapse
        // Collections

        #region colTasks
        private ObservableCollection<Task> _colTasks
            = new ObservableCollection<Task>();
        public ObservableCollection<Task> colTasks
        {
            get { return _colTasks; }
            private set
            {
                if (colTasks == value)
                {
                    return;
                }
                _colTasks = value;
                this.NotifyPropertyChanged("colTasks");
            }
        }
        #endregion

This is like a Property, but it holds a Collection of Tasks instead of a single value.

Add the following code to the class:

 Collapse
        
        // Operations

        #region GetTasks
        private void GetTasks()
        {
            // Clear the current Tasks
            colTasks.Clear();
            // Call the Model to get the collection of Tasks
            TasksModel.GetTasks((Param, EventArgs) =>
            {
                if (EventArgs.Error == null)
                {
                    // loop thru each item
                    foreach (var Task in EventArgs.Result)
                    {
                        // Add to the colTasks collection
                        colTasks.Add(Task);
                    }

                    // Count the records returned
                    if (colTasks.Count == 0)
                    {
                        // If there are no records, indicate that
                        Message = "No Records Found";

                        // Set HasCurrentTask
                        HasCurrentTask = Visibility.Collapsed;

                        // We have no Tasks so set HasTasks
                        HasTasks = Visibility.Collapsed;
                    }
                    else
                    {
                        // We have Tasks so set HasTasks
                        HasTasks = Visibility.Visible;
                    }
                }
            });
        }
        #endregion

        #region GetTask
        private void GetTask(int intTaskID)
        {
            // Call the Model to get the Task
            TasksModel.GetTask(intTaskID, (Param, EventArgs) =>
            {
                if (EventArgs.Error == null)
                {
                    // Set the CurrentTask Property
                    CurrentTask = EventArgs.Result;

                    // Set Visibility
                    HasCurrentTask = Visibility.Visible;
                    AddVisibility = Visibility.Visible;
                    UpdateVisibility = Visibility.Visible;
                    DeleteVisibility = Visibility.Visible;
                }
            });
        }
        #endregion

        #region DeleteTask
        private void DeleteTask(Task objTask)
        {
            // Call the Model to delete the Task
            TasksModel.DeleteTask(objTask.TaskID, (Param, EventArgs) =>
            {
                if (EventArgs.Error == null)
                {
                    // Set the Error Property
                    Message = EventArgs.Result;

                    // Set current Task to null
                    CurrentTask = null;

                    // Update the Tasks list
                    GetTasks();

                    // Set Visibility
                    HasCurrentTask = Visibility.Collapsed;
                    AddVisibility = Visibility.Visible;
                    UpdateVisibility = Visibility.Collapsed;
                    DeleteVisibility = Visibility.Collapsed;
                }
            });
        }
        #endregion

        #region UpdateTask
        private void UpdateTask(Task objTask)
        {
            // Call the Model to UpdateTask the Task
            TasksModel.UpdateTask(objTask, (Param, EventArgs) =>
            {
                if (EventArgs.Error == null)
                {
                    // Set the Error Property
                    Message = EventArgs.Result;

                    // Update the Tasks list
                    GetTasks();

                    // Set Visibility
                    HasCurrentTask = Visibility.Visible;
                    AddVisibility = Visibility.Visible;
                    UpdateVisibility = Visibility.Visible;
                    DeleteVisibility = Visibility.Visible;
                }
            });
        }
        #endregion

        #region InsertTask
        private void InsertTask(Task objTask)
        {
            // Call the Model to Insert the Task
            TasksModel.InsertTask(objTask, (Param, EventArgs) =>
            {
                if (EventArgs.Error == null)
                {
                    // Set the CurrentTask Property
                    CurrentTask = EventArgs.Result;

                    // Update the Tasks list
                    GetTasks();

                    // Set Visibility
                    HasCurrentTask = Visibility.Visible;
                    AddVisibility = Visibility.Visible;
                    UpdateVisibility = Visibility.Visible;
                    DeleteVisibility = Visibility.Visible;
                }
            });
        }
        #endregion

        #region SetToNewTask
        private void SetToNewTask()
        {
            // Create a empty Task
            // so form will be blank
            Task objTask = new Task();

            // Set TaskID = -1 so we know it's 
            // a new Task
            objTask.TaskID = -1;

            // Set the CurrentTask Property
            CurrentTask = objTask;

            // Set Visibility
            HasCurrentTask = Visibility.Visible;
            AddVisibility = Visibility.Collapsed;
            UpdateVisibility = Visibility.Visible;
            DeleteVisibility = Visibility.Collapsed;
        }
        #endregion

These are the operations that the View Model will perform. These are the methods that do the actual work. Mostly these methods simply call the methods in the Model.

Add the following code to the class:

 Collapse
     // Commands

        #region GetTasksCommand
        public ICommand GetTasksCommand { get; set; }
        public void GetTasks(object param)
        {
            GetTasks();
        }

        private bool CanGetTasks(object param)
        {
            return true;
        }
        #endregion

        #region GetTaskCommand
        public ICommand GetTaskCommand { get; set; }
        public void GetTask(object param)
        {
            // Get the Task that was passed as a parameter
            Task objTask = (Task)param;

            // Call GetTask to get and set
            // the CurrentTask property
            GetTask(objTask.TaskID);
        }

        private bool CanGetTask(object param)
        {
            // Only allow this ICommand to fire 
            // if a Task was passed as a parameter
            return ((param as Task) != null);
        }
        #endregion

        #region DeleteTaskCommand
        public ICommand DeleteTaskCommand { get; set; }
        public void DeleteTask(object param)
        {
            if (CurrentTask.TaskID == -1)
            {
                // This is a new Task
                SetToNewTask();
            }
            else
            {
                // This is an Existing Task
                DeleteTask(CurrentTask);
            }
        }

        private bool CanDeleteTask(object param)
        {
            // Do not allow if there is no Current Task
            return (CurrentTask != null);
        }
        #endregion

        #region UpdateTaskCommand
        public ICommand UpdateTaskCommand { get; set; }
        public void UpdateTask(object param)
        {
            if (CurrentTask.TaskID == -1)
            {
                // This is a new Task
                InsertTask(CurrentTask);
            }
            else
            {
                // This is an Update
                UpdateTask(CurrentTask);
            }
        }

        private bool CanUpdateTask(object param)
        {
            // Do not allow if there is no Current Task
            return (CurrentTask != null);
        }
        #endregion

        #region AddNewTaskCommand
        public ICommand AddNewTaskCommand { get; set; }
        public void AddNewTask(object param)
        {
            SetToNewTask();
        }

        private bool CanAddNewTask(object param)
        {
            return true;
        }
        #endregion

These are the ICommands. They will be called from the View.

In Visual Studio, select Build, then Build RIATasks.

The project should build without any errors.

Open the MainPage.xaml file in Expression Blend 4 (or higher).

The project will open in Expression Blend.

Click on LayoutRoot in the Objects and Timeline window, and in the Properties window, type DataContext in the Search box.

Next, Click the New button next to DataContext.

Select MainPageModel and click OK.

Click the Data tab and expand MainPageModel (under the Data Context section).

You will all the public PropertiesCollections, and ICommands that are in the MainPageModel.

Create Sample Data

It will be easier to design the form if we are also able to see sample data.

In the Data window, Click on the Create sample data icon.

Select Create Sample Data from Class…

Select the MainPageModel and click OK

You will now see the MainPageModelSampleData class.

Build the View

Click on colTasks in the Sample Data section…

…and drop it on the page.

It will create a ListBox with sample data. Note: At run-time the real data will show not the Sample Data.

In the Properties for the ListBox, set the HorizontalAlignment to Left, and the VerticalAlignment to Top

Right-click on the ListBox and select:

Edit additional Templates > Edit Generated Items > Edit Current

Click on the third TextBlock in the Objects and Timeline window

In the Properties for the TextBlock, select Advanced options next to Text

Select Data Binding

We see that this is bound to the TaskName. This is the only TextBlock that we want to show in the ListBox

In the Objects and Timeline window, delete the other three TextBlocks

Click the Return scope icon

The ListBox is now formatted

Now, select the Grid control

Draw a Grid next to the ListBox

Hover the mouse near the edge of the Grid, and click with the left mouse button, to make cells

From the Tools Bar, grab a TextBox

Draw a TextBox on the Grid

From the Data window, grab TaskName

Drag TaskName onto the TextBox

In the Properties for the TextBox:

  • Set the Width and Height to Auto
  • Set Horizontal and Vertical Alignment
  • Set all Margins to 0

Draw another TextBox on the Grid

In the Properties for the TextBox:

  • Set the Width and Height to Auto
  • Set Horizontal and Vertical Alignment
  • Set all Margins to 0

From the Data window, drag TaskDescription onto the TextBox

Drag TextBlocks onto the Grid for Name and Description labels, and set their Text Properties.

Click on Button in the Tools Bar

Draw a Button above the ListBox

Set the Content of the button to Add

Add an Update and Delete button

(we will set the button’s Click events in a later step)

Setting Visibility

We now have all the controls on the page, we will now hook up the Visibility for the various controls

Click on the Grid in the Objects and Timeline window

In the Properties for the Grid, select Advanced options for Visibility

Select Data Binding…

Bind to HasCurrentTask and click OK

Hook up the remaining Visibility Properties according to the diagram above.

Note: If binding the Visibility causes some elements to disappear in Design mode, you can edit the sample data file…

…and set them to Visible

Using Behaviors

We will now use the InvokeCommandAction behavior to allow the buttons to raise ICommands in the View Model.

Add Button

Get an InvokeCommandAction Behavior.

Drop it on the Add button in the Objects and Timeline window

In the Properties for the Behavior:

  • Select Click for EventName
  • Click Data bind icon next to Command (under Common Properties)

Select the Data Context tab and then select AddNewTaskCommand and click OK.

Add InvokeCommandAction Behaviors to the Update and Delete buttons according to the diagram above.

Selecting A Task From The ListBox

  • Drop an InvokeCommandAction behavior to the ListBox.
  • Set the EventName to SelectionChanged
  • Click Data bind next to Command

Select GetTaskCommand and click OK

Click Advanced options next to CommandParameter

Select the SelectedItem from the ListBox and click OK

Add Styling

image

See the article at this link to obtain the ResourceDictionary for the style, and the directions on how to apply it.

Build And Run The Project

In the Projects window, right-click on the RIATasks.Web project and select Startup Project

Right-click on the Default.aspx page and select Startup

Hit F5 to Build and Run the project

The project is complete.

Use View Model When You Want To Write Less Code

Bindings combined with INotifyPropertyChanged, can save you from writing a lot of code. Using View Model allows you to leverage a lot of the helpful features in Microsoft Expressions BlendView Model is also a simple pattern to follow, so you can quickly and easily implement Properties,Collections and ICommands.

The actual “custom code” is contained in the “Operations” section of the View Model. You will see that it is not a lot of code and most of it is simply calling the Model and setting a Property in the View Model. Also note, that when an object such as “Task” is set as the current Task selected, we never need to split out each of the fields in the Task object and process each separately, we just pass the actual “Task” object between the Model,View Model, and View.

It is very helpful that we can expose Properties, such as custom objects like Task and Visibility, to the View as they are, and let the Designer worry about how to actually implement them. Even if we are also the Designer, we can use the drag and drop features of Expression Blend to quickly, and accurately assemble the UI.

The programmer can simply concentrate on getting the data in and out of the View Model, through the Model, and enforcing business rules. This allows the Programmer to focus on a clear easily testable task. The UI issues are abstracted away.

This I believe is where a programmer will discover that they will use LESS CODE than if they did not use View Model. At the very least, many programmers I have worked with, find the experience more enjoyable because they can focus on the procedural logic.

4 Simple Steps to Consume WCF Service using Silverlight


4 Simple Steps to Consume WCF Service using Silverlight

Video demonstration One Way, Two Way and One Time Bindings using Silver light

Introduction

This article will talk about 4 simple steps which will assist you to consume WCF service in a Silverlight application. It also has a simple sample source code which demonstrates all the 4 steps practically.

I have collected around 400 FAQ questions and answers in WCF, WPF, WWF, SharePoint, design patterns, UML, etc. Feel free to download these FAQ PDFs from my site http://www.questpond.com.

Step 1: Create Your WCF Service

The first step is to create your WCF service. When we create a WCF service, by default it creates ‘GetData’ function which takes in an integer value and returns back a string saying “You entered 10” , in case you passed ‘10’ as value to the function. We will try to consume this service in Silverlight in the coming steps:

 Collapse
public class Service1 : IService1
{
    public string GetData(int value)
    {
        return string.Format("You entered: {0}", value);
    }
}

Step 2: Enable Cross Domain for Your WCF Service

For this example, our WCF service and the Silverlight web application will be hosted in different IIS websites. In other words, they will be hosted in different domains. When we talk about different website, in other words they are hosted in different domains. For instance, it’s possible that your Silverlight web application is hosted in one domain like www.xyz.com  and your WCF service is hosted in different domain i.e. www.pqr.com.

The WCF service needs to enable cross domain facility so that other domains can consume the WCF service.

Figure: Cross domain

We need to create two XML files (clientaccesspolicy.xml and crossdomain.xml) in the root directory of the WCF service to enable cross domain functionality.
Below is the XML code snippet for clientaccesspolicy.xml:

 Collapse
<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource include-subpaths="true" path="/"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>

Below is the XML code snippet for crossdomain.xml:

 Collapse
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM 
	"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>

Step 3: Add the WCF Service Reference

Create a simple Silverlight application and add the service reference to your Silverlight project. In order to call the WCF service, we need to define event handlers.

To consume the WCF service is a three step procedure.

  • In the first step, refer to the name space.
  • In the second step, create the object of your WCF service.
  • In the final step, we need to create an event handler which will get the results sent by the WCF service.

One of the important points to note is that the function ‘GetData’ is called asynchronously.

Step 4: Call the Service

Finally compile the program and enjoy the output.