[Silverlight 2.0, C#] Creating a database-driven Line Of Business application

June 9th, 2009 Donavan Marais No comments

Today I am going to step through creating a database-driven multipage application that will allow new users to register a new profile, and then log in thereafter. In addition, the app will feature an admin log in for admin to view registered users with the results displaying in a datagrid. In later posts, we’ll explore styling of the datagrid.

This post will consist of a couple of posts as the explanation is too long for one article. First a disclaimer: I am not a graphics designer, so if you can improve on the UI, please go ahead. I hope you’ll appreciate what I’ve put together.

We’ll include a typical form that collects data from the user and then a summary page that will display the information back to the user for final confirmation. Once the user has been successfully registered, a login screen will show allowing the user to log in. The data entered will be written to a SQL database.

We’ll be using a Silverlight-enabled WCF Service and LINQ to SQL to access the data from the SQL database. We’ll be creating the SQL database from scratch as well.

I am going to assume that you have the required software and tools to follow along with this post. If you’re unsure, here is a quick overview of what you’ll need:

1. Visual Studio 2008, or Visual Web Developer E2008 Express (download it here, if need be: http://www.microsoft.com/express/vwd/).

2. Visual Studio SP1 (download it here, if need be: http://www.microsoft.com/downloads/details.aspx?familyid=FBEE1648-7106-44A7-9649-6D9F6D58056E&displaylang=en).

3. Microsoft® Silverlight™ 2 Tools for Visual Studio 2008 SP1 (download it here, if need be:  http://www.microsoft.com/downloads/details.aspx?familyid=C22D6A7B-546F-4407-8EF6-D60C8EE221ED&displaylang=en).

4. Microsoft Expression Blend 2  Trial Version (download it here, if need be: http://www.microsoft.com/downloads/details.aspx?FamilyId=5FF08106-B9F4-43CD-ABAD-4CC9D9C208D7&displaylang=en).

5. Microsoft Expression Blend 2 SP1 (download it here, if need be: http://www.microsoft.com/downloads/details.aspx?FamilyId=EB9B5C48-BA2B-4C39-A1C3-135C60BBBE66&displaylang=en).

6. Microsoft SQL Server 2005 Express (download it here, if need be: http://www.microsoft.com/downloads/details.aspx?familyid=220549b5-0b07-4448-8848-dcc397514b41&displaylang=en).

7. Something extra that will help is Microsoft SQL Server Management Studio Express to aid in creating SQL databases and navigate your tables, import databases, etc. (download it here, if need be: http://www.microsoft.com/downloads/details.aspx?familyid=C243A5AE-4BD1-4E3D-94B8-5A0F62BF7796&displaylang=en).

That’s it. If you need help in installing any of these tools, please send me an comment and I’ll be sure to point you in the right direction. Oh, by the way, please follow the steps for installation. I found out the hard way that failing to do so results in a broken installation of the Silverlight Tools in Visual Studio. I will also assume that you are starting from scratch and have no prior installation of Visual Studio. If you have Visual Studio 2005, please uninstall it, including all associated tools, or you may have problems later.

Right, now that we have handled some admin, let’s get on with the post, shall we?

Start a new Silverlight 2 application and name it MultiPageApp. If you are unsure how to do this, please refer to my post on creating a pop up window, which has details on how to do this: http://2browndogs.com/?p=11 (passing an image to a pop up window).

Here follows a couple screenshots of what we are going to build:

First screenshot shows the main page that initially opens in the browser

page_screenshot5

 This screenshot shows the user registration page

user_registration_screenshot2

 This screenshot shows the user login page

user_login_screenshot

Finally, last screenshot showing the admin login

admin_login_screenshot1

So as you can see, not a very complicated UI at all. By the way, the company logo will serve a button to return the user to the main page to aid in navigation.

 Once your new Silverlight 2 application startup files have been created in Visual Studio, you should have both your client and server files showing. Page.xaml will automatically open for you. You’ll notice that the page opens showing dual view of both XAML and Preview mode. If you would prefer to have Visual Studio automatically open XAML pages in the XAML code rather, go to Tools, Options, Text Editor, scroll down to XAML, then Miscellaneous, and click the box for Default View to always open documents in full XAML view.

Let’s immediately add our extra XAML pages that we’ll need for user login, user registration, admin login and navigation. We’ll call them Login.xaml, Register.xaml, Admin.xaml, and Navigation.xaml respectively. Just to reiterate, to add these pages, right click on the client-side project file, (MultiPageApp, not MultiPageApp.Web) and choose Add -> New Item ->Silverlight User Control.

Visual Studio automatically creates the code behind pages for you. Great! Let’s start with Page.xaml and add our elements. Bear in mind that our 3 buttons are actually part of Navigation.xaml and at runtime we’ll load in this page as a child element to a grid that we’ll place on Page.xaml. It’ll make sense once we go through the steps. The benefit of following this practice is to improve efficiency of your app to avoid unnecessary reloading of page elements.

With Page.xaml open, let’s lay our page out as follows. Remove the height and width properties for the user control. This will enable our page to render in the entire browser window. Our app is going to have a liquid layout and will automatically adjust to the browser window without any extra coding. I like this feature as it eliminates the need for any JavaScript. This is a cross-browser, cross-platform application after all.  Next remove the background color of our grid (LayoutRoot).  Now add a row and a column:

<Grid.RowDefinitions>

            <RowDefinition Height=”*” />

</Grid.RowDefinitions>

 

<Grid.ColumnDefinitions>

      <ColumnDefinition Width=”*” />

</Grid.ColumnDefinitions>

 We’ll set the height and width using an ‘*’, which allows the height and width to be proportionate to the browser window and the user control’s elements. 

 Now we’ll nest a grid within our LayoutRoot grid, assign rows and columns, set our background as a color gradient, and add our company logo:  

 

<Grid Height=”Auto” HorizontalAlignment=”Stretch” Margin=”0,0,0,0″ VerticalAlignment=”Stretch” Width=”Auto”>

 

            <Grid.ColumnDefinitions>

            <ColumnDefinition Width=”20″/>

                        <ColumnDefinition Width=”100″/>

                        <ColumnDefinition Width=”900″/>

            </Grid.ColumnDefinitions>

 

            <Grid.RowDefinitions>

            <RowDefinition Height=”20″/>

                        <RowDefinition Height=”100″/>

                        <RowDefinition Height=”700″/>

            </Grid.RowDefinitions>

 

            <Grid.Background>

                        <LinearGradientBrush EndPoint=”0.5,1″ StartPoint=”0.5,0″>

                                    <GradientStop Color=”#FF0A2148″/>

                                    <GradientStop Color=”#FFD3D7DD” Offset=”1″/>

                        </LinearGradientBrush>

            </Grid.Background>

 

            <Image Height=”Auto” Width=”Auto” Source=”Images/MyLogo.png” RenderTransformOrigin=”0.51,0.42″ Margin=”0,0,0,0″ Grid.Row=”1″ Grid.Column=”1″ />

 

</Grid>

The company logo is included in my source files; I created that so you are welcome to use it. Lastly, we are going to add an extra grid, which will act as a parent grid, into which we’ll load its children that being our navigation, login, etc.

<Grid Margin=”0,0,0,0″ x:Name=”grdMain” HorizontalAlignment=”Center” VerticalAlignment=”Center” />

This grid’s name is grdMain and you’ll see how we refer to it in our code behind page.

Let’s create the elements on the Navigation.xaml page, which will consist of a stackpanel with 3 buttons. You’ll need to remove the grid first. Next add a stackpanel, and then add 3 buttons. Remove the height and width properties for the user control:

<StackPanel Margin=”0,0,0,0″ Orientation=”Horizontal” x:Name=”spNavigation”>

 

        <Button Height=”118.865″ Width=”172.638″ Content=”User Registration” x:Name=”btnRegister” Cursor=”Hand” FontFamily=”./Fonts/Fonts.zip#Arial Rounded MT” FontSize=”14″ Foreground=”#FF1F3B53″ Click=”btnRegister_Click” />

        <Button Height=”119″ Width=”173″ Content=”User Login” Cursor=”Hand” x:Name=”btnLogin” FontFamily=”./Fonts/Fonts.zip#Arial Rounded MT” FontSize=”14″ Foreground=”#FF1F3B53″ Margin=”30,0,30,0″ Click=”btnLogin_Click” />

        <Button Height=”119″ Width=”173″ Content=”Admin Login” x:Name=”btnAdminLogin” Cursor=”Hand” Foreground=”#FF1F3B53″ FontFamily=”./Fonts/Fonts.zip#Arial Rounded MT” FontSize=”14″ Click=”btnAdminLogin_Click”/>

</StackPanel>

You’ll notice that I’m making use of the Arial Rounded MT font, which I’ve embedded, since Blend does not include this font within your font license library. If you do make use of this font outside production, you may need to ensure that you have the required publishing license for that font, or you may run into some issues later.

I’ve given each button a name and set it’s cursor to a hand, so help the user identify the button as such. In addition, each button has a click event. I let Visual Studio add them for me, by tabbing through the code after typing in “Click”. If you navigate to the code behind, you’ll notice that Visual Studio adds the event handler code for each event.

So if you haven’t already done so, please open Navigation.xaml.cs to edit the event handlers for the 3 buttons.

Add the following code to each event handler:

private void btnRegister_Click(object sender, RoutedEventArgs e)

{

     this.Content = new Register();

}

 

private void btnLogin_Click(object sender, RoutedEventArgs e)

{

     this.Content = new Login();

}

 

private void btnAdminLogin_Click(object sender, RoutedEventArgs e)

{

     this.Content = new Admin();

}

 Allow me to explain. What we are doing here is changing out the current child to a new child. In other words, this.Content = new Register(); means take this content’s child, remove it and then add a newly instantiated page, called Register to grdMain, as its new child and then display it to the user. Pretty simple and efficient.

Right, let’s now go to Page.xaml.cs to add a loaded event, to add this page at runtime to our grdMain.

In the constructor, add a loaded event delegate:

            Loaded += new RoutedEventHandler(Page_Loaded);

Visual Studio will automatically add “Page_Loaded” after you begin typing “Loaded” and then “+=”. When you get to this point, immediately press the tab key and the Page_Loaded  event is added.

Now add the following code to this event, but first remove the line of code that is contained:

public void Page_Loaded(object sender, RoutedEventArgs e)

{

    grdMain.Children.Clear();

    Navigation navigation = new Navigation();

    grdMain.Children.Add(navigation);

}

 

This event will accomplish 3 things:

1.       Clear any children that grdMain may have loaded.

2.      Instantiate a new user control, that being Navigation.

3.      Next, add this user control to our grid, grdMain as a child.

You might recall when we lay Page.xaml out, we added an image for our company logo. Let’s now add some extra properties to that image element.  Add:

MouseLeftButtonDown=”Page_Go” Cursor=”Hand” ToolTipService.ToolTip=”Take me back to the home page”

to that image element. Make sure you image look like this:

<Image Height=”Auto” Width=”Auto” Source=”Images/MyLogo.png” RenderTransformOrigin=”0.51,0.42″ Margin=”0,0,0,0″ Grid.Row=”1″ Grid.Column=”1″ MouseLeftButtonDown=”Page_Go” Cursor=”Hand” ToolTipService.ToolTip=”Take me back to the home page”/>

I’ve added a cursor and a ToolTipService property as well. The ToolTipService is a handy way of providing a special message when the user’s cursor hovers over the image.

Build the app, run it and you should now see Page.xaml open with Navigation.xaml dynamically loaded in as a child in grdMain. If so, then you’re on the right track! Your screen should look like the screenshot I have at the top of this page.

So far so good, now we’ll add the user control elements for each of the pages that the buttons will open. Open Login.xaml and let’s add a border to our grid. Remember to remove the width and height properties for this user control. This border will wrap around any elements we nest within our grid:

<Border Margin=”0,0,0,0″ CornerRadius=”10,10,10,10″ Background=”#FFB9D0E8″ BorderBrush=”#FF113150″ BorderThickness=”2,2,2,2″>

</Border>

Our border has a radius, a background color, a border stroke, and a stroke thickness. Next we nest a stackpanel within our border element:

<StackPanel Height=”Auto” Width=”Auto” HorizontalAlignment=”Center” VerticalAlignment=”Center” x:Name=”spWrapper” Margin=”20,20,20,20″>

</StackPanel>

Let’s add a textblock for our page title:

<TextBlock Height=”Auto” HorizontalAlignment=”Center” VerticalAlignment=”Center” Width=”Auto” FontFamily=”./Fonts/Fonts.zip#Arial Rounded MT” FontSize=”14″ FontWeight=”Bold” Foreground=”#FF113150″ Text=”User Login” TextWrapping=”NoWrap” TextAlignment=”Center” Margin=”0,0,0,0″ x:Name=”txtTitle”/>

Next, we’ll add 3 stackpanels; the first for the username label and textbox, the second for the password label and textbox, and the last for the 2 buttons, for login and for forgot password:

First Stackpanel

<StackPanel Height=”Auto” Width=”Auto” Orientation=”Horizontal” HorizontalAlignment=”Stretch” VerticalAlignment=”Stretch” x:Name=”spUsername” Margin=”0,10,0,5″>

</StackPanel>

 

Second Stackpanel

<StackPanel Height=”Auto” Width=”Auto” Orientation=”Horizontal” HorizontalAlignment=”Stretch” VerticalAlignment=”Stretch” x:Name=”spPassword” Margin=”0,5,0,5″>

</StackPanel>

Third Stackpanel

            <StackPanel Height=”Auto” Width=”Auto” Orientation=”Horizontal” HorizontalAlignment=”Center” VerticalAlignment=”Center” x:Name=”spButtons” Margin=”0,20,0,0″>

            </StackPanel>

Right before we go on, we need to add a reference to the new Silverlight 2 Toolkit March 2009 Release, so that we can utilize the new password box. If you need to download the binary, you’ll find it here: http://silverlight.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=20430. Make sure you download the Silverlight 2 version. Once installed, go to your client side and right click on References, add Reference. An Add Reference dialog window opens. On the .Net tab, scroll down to System.Tools.Controls. Click OK. Great, now let’s add the binary to our page. At the top of Login.xaml, in the user control element, add the following property:

            xmlns:t=”clr-namespace:System.Windows.Controls;assembly=System.Windows”

Incidently, I added the “:t” just after the “xmlns”. By doing so, you are now able to reference this binary within your xaml, by typing <t:  …>. Visual Studio automatically adds all the controls of that binary to intellisense, and all you have to do is make your choice. Now we can access the password control.

Next, we need to add a reference to System.Windows.Controls.Toolkit, to access the Label control:

            xmlns:u=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit”

So, let’s go ahead and first add our label and textbox for username to our first stackpanel, between the opening and closing tag:

            <u:Label Height=”Auto” Width=”120″ Content=”Username:” Margin=”0,0,0,0″ x:Name=”lblUsername” FontFamily=”Arial” FontSize=”12″ Foreground=”#FF000000″ />             

            <TextBox x:Name=”txtUsername” Width=”150″ />

As I mentioned before, open a new tag, start typing ‘u’, and intellisense takes over. Scroll down the list until you find Label.

Next, we add the label and password box for the second stackpanel:

            <u:Label Height=”Auto” Width=”120″ Content=”Password:” Margin=”0,0,0,0″ x:Name=”lblPassword” FontFamily=”Arial” FontSize=”12″ Foreground=”#FF000000″ />

      <t:PasswordBox x:Name=”txtPassword” Width=”150″ />

Lastly, we create the 2 buttons to be placed in the third stackpanel:

            <Button Height=”32″ Width=”102″ Content=”Login” Margin=”0,0,5,0″/>

            <Button Height=”32″ Width=”102″ Content=”Forgot password” Margin=”5,0,0,0″/>

 

Let’s build our app and run it. If you click on the user login button and the navigation stackpanel will be replaced by the login page you just completed. Excellent! 3 more pages to go.

Let’s now add the elements to our admin login page. We’ll come back to the register page later. Admin.xaml is almost identical to Login.xaml. Here is the completed code, with no explanation required:

            UserControl x:Class=”MultiPageApp.Admin”

            xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

            xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”

            xmlns:t=”clr-namespace:System.Windows.Controls;assembly=System.Windows”

            xmlns:u=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit”>

   

            <Grid x:Name=”LayoutRoot”>

       

                        <Border Margin=”0,0,0,0″ CornerRadius=”10,10,10,10″ Background=”#FFB9D0E8″ BorderBrush=”#FF113150″ BorderThickness=”2,2,2,2″>

                                   

<StackPanel Height=”Auto” Width=”Auto” HorizontalAlignment=”Center” VerticalAlignment=”Center” x:Name=”spWrapper” Margin=”20,20,20,20″>

 

                                                <TextBlock Height=”Auto” HorizontalAlignment=”Center” VerticalAlignment=”Center” Width=”Auto” FontFamily=”./Fonts/Fonts.zip#Arial Rounded MT” FontSize=”14″ FontWeight=”Bold” Foreground=”#FF113150″ Text=”Admin Login” TextWrapping=”NoWrap” TextAlignment=”Center” Margin=”0,0,0,0″ x:Name=”txtTitle”/>

 

                                                <StackPanel Height=”Auto” Width=”Auto” Orientation=”Horizontal” HorizontalAlignment=”Stretch” VerticalAlignment=”Stretch” x:Name=”spUsername” Margin=”0,10,0,5″>

                                                            <u:Label Height=”Auto” Width=”120″ Content=”Username:” Margin=”0,0,0,0″ x:Name=”lblUsername” FontFamily=”Arial” FontSize=”12″ Foreground=”#FF000000″ />

                                                            <TextBox x:Name=”txtUsername” Width=”150″ />

                                                </StackPanel>

 

                                                <StackPanel Height=”Auto” Width=”Auto” Orientation=”Horizontal” HorizontalAlignment=”Stretch” VerticalAlignment=”Stretch” x:Name=”spPassword” Margin=”0,5,0,5″>

                                                            <u:Label Height=”Auto” Width=”120″ Content=”Password:” Margin=”0,0,0,0″ x:Name=”lblPassword” FontFamily=”Arial” FontSize=”12″ Foreground=”#FF000000″ />

                                                            <t:PasswordBox x:Name=”txtPassword” Width=”150″ />

                                                </StackPanel>

 

                                                <StackPanel Height=”Auto” Width=”Auto” Orientation=”Horizontal” HorizontalAlignment=”Center” VerticalAlignment=”Center” x:Name=”spButtons” Margin=”0,20,0,0″>

                                                            <Button Height=”32″ Width=”102″ Content=”Login” Margin=”0,0,5,0″/>

                                                            <Button Height=”32″ Width=”102″ Content=”Forgot password” Margin=”5,0,0,0″/>

                                                </StackPanel>

 

                                                </StackPanel>

                        </Border>

       

            </Grid>

   

       </UserControl>

So be sure to build and test your app. If successful, when you click on the admin login button, the navigation stackpanel should be replaced with the UI you just completed.

Now lets create the elements for the registration page. This page is similar to the login page, but with some extra controls for the extra information we’ll need to write to the database to register the user.

So I won’t go into too much detail here. Once again, the completed source code:

            <UserControl x:Class=”MultiPageApp.Register”

            xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

            xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”

            xmlns:u=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit”>

   

            <Grid x:Name=”LayoutRoot”>

       

        <Border Margin=”0,0,0,0″ CornerRadius=”10,10,10,10″ Background=”#FFB9D0E8″ BorderBrush=”#FF113150″ BorderThickness=”2,2,2,2″>

           

            <StackPanel Height=”Auto” Width=”Auto” HorizontalAlignment=”Center” VerticalAlignment=”Center” x:Name=”spWrapper” Margin=”20,20,20,20″>

 

                <TextBlock Height=”Auto” HorizontalAlignment=”Center” VerticalAlignment=”Center” Width=”Auto” FontFamily=”./Fonts/Fonts.zip#Arial Rounded MT” FontSize=”14″ FontWeight=”Bold” Foreground=”#FF113150″ Text=”User Login” TextWrapping=”NoWrap” TextAlignment=”Center” Margin=”0,0,0,0″ x:Name=”txtTitle”/>

 

                <StackPanel Height=”Auto” Width=”Auto” Orientation=”Horizontal” HorizontalAlignment=”Stretch” VerticalAlignment=”Stretch” x:Name=”spUsername” Margin=”0,10,0,5″>

                    <u:Label Height=”Auto” Width=”120″ Content=”Username:” Margin=”0,0,0,0″ x:Name=”lblUsername” FontFamily=”Arial” FontSize=”12″ Foreground=”#FF000000″ />

                    <TextBox x:Name=”txtUsername” Width=”150″ />

                </StackPanel>

 

                <StackPanel Height=”Auto” Width=”Auto” Orientation=”Horizontal” HorizontalAlignment=”Stretch” VerticalAlignment=”Stretch” x:Name=”spPassword” Margin=”0,5,0,5″>

                    <u:Label Height=”Auto” Width=”120″ Content=”Passsword:” Margin=”0,0,0,0″ x:Name=”lblPassword” FontFamily=”Arial” FontSize=”12″ Foreground=”#FF000000″ />

                    <TextBox x:Name=”txtPassword” Width=”150″ />

                </StackPanel>

               

                <StackPanel Height=”Auto” Width=”Auto” Orientation=”Horizontal” HorizontalAlignment=”Stretch” VerticalAlignment=”Stretch” x:Name=”spFName” Margin=”0,5,0,5″>

                    <u:Label Height=”Auto” Width=”120″ Content=”Full Name:” Margin=”0,0,0,0″ x:Name=”lblFName” FontFamily=”Arial” FontSize=”12″ Foreground=”#FF000000″ />

                    <TextBox x:Name=”txtFName” Width=”150″ />

                </StackPanel>

               

                <StackPanel Height=”Auto” Width=”Auto” Orientation=”Horizontal” HorizontalAlignment=”Stretch” VerticalAlignment=”Stretch” x:Name=”spLName” Margin=”0,5,0,5″>

                    <u:Label Height=”Auto” Width=”120″ Content=”Last Name:” Margin=”0,0,0,0″ x:Name=”lblLName” FontFamily=”Arial” FontSize=”12″ Foreground=”#FF000000″ />

                    <TextBox x:Name=”txtLName” Width=”150″ />

                </StackPanel>

               

                <StackPanel Height=”Auto” Width=”Auto” Orientation=”Horizontal” HorizontalAlignment=”Stretch” VerticalAlignment=”Stretch” x:Name=”spEmail” Margin=”0,5,0,5″>

                    <u:Label Height=”Auto” Width=”120″ Content=”Email:” Margin=”0,0,0,0″ x:Name=”lblEmail” FontFamily=”Arial” FontSize=”12″ Foreground=”#FF000000″ />

                    <TextBox x:Name=”txtEmail” Width=”150″ />

                </StackPanel>

 

                <StackPanel Height=”Auto” Width=”Auto” Orientation=”Horizontal” HorizontalAlignment=”Center” VerticalAlignment=”Center” x:Name=”spButtons” Margin=”0,20,0,0″>

                    <Button Height=”32″ Width=”102″ Content=”Register” Margin=”0,0,0,0″ Cursor=”Hand” x:Name=”btnRegister”/>

                </StackPanel>

 

            </StackPanel>

           

        </Border>

       

    </Grid>

   

</UserControl>

Now once again, build your app and you should be good to go. Click on the user register button and you should see the register UI.

Well that’s it for now. I hope you’ve enjoyed this post. Please be sure to send any comments or suggestions you may have.

Please return soon as I’ll be posting the second part of this post.

You may download the source code HERE.

 

[Silverlight 2.0, C#] Passing an image to a pop-up window

May 7th, 2009 Donavan Marais 7 comments

This is the first of my many blogs. In fact, I plan to publish a new article each week where I’ll be discussing whatever it is I’m working on or appeals to me. Some of my articles will discuss a problem and some possibilities to solve it. Others may need your help. I plan to keep the articles simple in nature as they are intended to help beginners as they embark on their development journeys. All my code will be in C#. I will not be able to help you if you require examples in Visual Basic.

If so, you can always find an online code convertor, such as at http://www.developerfusion.com/tools/convert/csharp-to-vb/

Today I’m going to discuss the concept of passing an image from a user control to a pop-up window. This could be handy when you need to show a user more details on a particular product. I’ll leave it up to your imagination. Here is a screenshot of what we’re going to build:

popup window showing image
So let’s start by creating a new Silverlight application. I am going to assume that you have the correct software required and that you’re ready to go.
If not, please refer to the Silverlight website for more info http://silverlight.net/GetStarted/.

Using Visual Studio 2008, go to File, New Project. Next select Visual C#, Silverlight, Silverlight Application.

newproject

Give your project a name. I’ve called mine PopUpWindow.

slproject1
Once you click OK, you will be asked how you want to host your Silverlight application. You have 2 choices, and I typically choose the first option, which adds my server side files to my app.

addslapp1

After clicking OK, Visual Studio will now go ahead and create 2 parts to your application, the client and the server side files.

solutionexplorer1
In my solution, I have PopUpWindow and PopUpWindow.Web, where the first is my client-side and the second my server-side files. All these files are created as part of your solution. We’ll discuss the server-side later, and focus on the client-side instead.  PopUpWindow contains our Properties, References, App and Page files. We’ll only be concentrating on our Page.xaml for now.

page1

Visual Studio presents us with 2 views of Page.xaml, that being the Preview and the XAML code. Double click the XAML tab for now. Unlike using Blend to edit your user control in a WYSIWYG fashion, Preview allows you to see how your page will render.

Remove the Width=”400″ Height=”300″ from UserControl tag. By removing the width and height, we enable the page to fill the browser window. Remove the Background=”White” code from the Grid tag. We’ll use a color gradient instead. We’ll add 2 rows to our grid as follows:

<Grid.RowDefinitions>
 <RowDefinition Height=”*”/>
 <RowDefinition Height=”Auto”/>
</Grid.RowDefinitions>

Next we’ll add a color gradient. You may do this in XAML code or in Blend. For simplicity, I’m going to code it instead.

<Grid.Background>
 <LinearGradientBrush EndPoint=”0.5,1″ StartPoint=”0.5,0″>
 <GradientStop Color=”#FF07144C”/>
 <GradientStop Color=”#FF385BEC” Offset=”1″/>
 </LinearGradientBrush>
</Grid.Background>

Now we’ll add a text block to the first row in our grid.

<TextBlock Margin=”0,0,0,0″ Text=”Click image to see larger version” TextWrapping=”Wrap” FontSize=”22″
Foreground=”#FFFFFFFF” FontWeight=”Bold” FontFamily=”Arial” HorizontalAlignment=”Center”
VerticalAlignment=”Center”/>

I’ve aligned the text block to the center of the row using using the Horizontal and Vertical Alignment. Now I add an image placeholder:

<Image x:Name=”MyImagePage” Margin=”0,0,0,0″ Grid.Row=”1″ Source=”Images/Sunset.jpg” HorizontalAlignment=”Center”
VerticalAlignment=”Center” Width=”500″ Height=”500″ Cursor=”Hand”/>

Let’s step through this step. We first need to add our image to our solution, so first add a new folder, called images. Right-click on your solution, Add, New Folder.

new-folder

Name it images. Next, right-click on your new folder, and Add, Existing Item.

images-to-folder

Browse to the folder where you would like to retrieve images from. For this exercise I’ve used the standard images as installed in My Pictures.

Build the project by going to Build, Build Solution, or hitting the shortcut key F6. You should have no errors. Going to Solution Explorer, go to your server-side files and right-click on PopUpWindowTestPage.aspx, View in browser.

view-in-browser

This is what you should see:

sofar

We are going to add an event handler on our image, so the when the user clicks on the image, a pop-up window will open with the image in place.
Right-click on your cient-side files (PopUpWindow), Add, New Item. An Add New Item dialog window will open.

addnewitem

Choose Silverlight User Control, and name it DetailsView.xaml. Click Add.

newitem

Visual Studio will now add your new xaml page and immediately open it in split view. Double click the XAML tab. Once again remove the height and width properties, and the background color property. We are going to nest a Popup control within our grid. Add a Popup control and name it ImagePopUp. Whenever you add controls to your UI, remember to assign it a name, using the x:Name property. This will ensure that you can reference it from code behind. Now within the Popup control, nest a grid, and call it ImageInfo. Add a background color property #80000000. Add a row and column definition to your grid:

<Grid.RowDefinitions>
 <RowDefinition />
 <RowDefinition Height=”auto” />
 <RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
 <ColumnDefinition />
 <ColumnDefinition Width=”auto” />
 <ColumnDefinition />
</Grid.ColumnDefinitions>

Our grid has 3 rows and 3 columns. The center row and column is set to auto width and height and will adjust to the border size. Now let’s add a border to our grid:

<Border Grid.Column=”1″ Grid.Row=”1″ BorderBrush=”#00000000″ BorderThickness=”1,1,1,1″ Width=”570″ Height=”340″
Padding=”10,10,10,10″ CornerRadius=”25,25,25,25″ Background=”#FF204FB7″>

Our border’s height is set to 340 and width to 570. Make the corners round by adding a CornerRadius property. Give the background a color.

If you’ve noticed, I did not close the border tag. The reason being is that we are going to nest our controls within the border tag. Lets add a stack panel to our border. Stack panels allow you to stack controls either horizontally or vertically. I’ll discuss layout controls in future articles. Add a stack panel and assign its orientation property to vertical. Don’t forget to give it a name.

<StackPanel Height=”Auto” Width=”Auto” Orientation=”Vertical” x:Name=”spMain”>

Our grid will contain 3 controls, a text block for the page title, a close button and an image placeholder. Let’s add our textblock:

<TextBlock x:Name=”tbHeading1″ Height=”Auto” Width=”Auto” Text=”Image Details” FontFamily=”Arial” FontSize=”14″
Foreground=”#FFFFFFFF” TextWrapping=”Wrap” TextAlignment=”Center” FontWeight=”Bold” />

Next we add our close button:

<Button x:Name=”btnClosePopup” Height=”30″ Width=”80″ Content=”Close”/>

Finally, we add our image placeholder and set its height and width:

<Image Height=”250″ Width=”400″ x:Name=”MyImageDetails”/>

The DetailsView page is completed for now. But Page.xaml does not connect to our DetailsView.xaml yet. We wire up the 2 pages through the click event handler on the image placeholder on Page.xaml. Let’s add a click event handler to our image. Images have a number of events that you can use, such as MouseLeftButtonDown, MouseLeftButtonUp, MouseEnter, MouseLeave, and MouseMove. We are going to use the MouseLeftButtonDown property. Start typing Mouse and intellisense will bring up the property selections:

mouseevents

Choose MouseLeftButtonDown and immediately intellisense will ask if it can automatically create an event handler in code behind for you.

neweventhandler

Accept the option by pressing the tab key. Click save, or use the short cut key Ctrl-S. Go to your Solution Explorer, PopUpWindow, and click the plus sign to the left of Page.xaml. You are now drilling down into the code behind page, Page.xaml.cs. This page is used for all the page logic behind your xaml page. This is where you assign your page properties, constructor, methods, and event handlers. When adding controls to your page, you can either do so in xaml or you may code it in C#. The choice is yours. More about this later. You will notice that your code behind page now has a constructor and the event handler intellisense created for you:

codebehind

Quick side note to all your aspiring developers. While you are coding, remember to add comments and keep your code neat and tidy. You never know when you’ll need to return to your code for revisions. It’s not uncommon to return to your code 6 months down the line and have no idea what you were trying to do there. Comments not only help you remember, but help your colleagues know what you were up to. When adding properties, methods, and event handlers, use region tags to keep them together:

#region Properties
.
.
Your code here…
.
.
#endregion Properties

Lay out your code with Properties at the top, then your constructor, your methods and then your event handlers. Keep this standard throughout your code and you’ll quickly see the benefit.  Right, now are going to wire up our application. Before we can use our DetailsView popup, let’s add a refernce to it in our Page.xaml by adding xmlns:p=”clr-namespace:PopUpWindow” as a property to our User Control tag.

This technique is very handy indeed. Later on, you might like to use third party controls in your app and after downloading the binary, aka the dll file, you can
add it as a reference within your reference folder on your client-side folder. Thereafter, to use that control, simply add the reference property to your xaml page. More on this later. If you’ve noticed, I named my reference p. To use this reference, simply open a new tag and type p. Intellisense will take over again:

<p:DetailsView x:Name=”myDetailsView” Visibility=”Collapsed” />

We leave the control as collapsed and change the visibility as and when needed. Let’s go ahead and start adding some code to our DetailsView.xaml.cs page.
We are going to add a property for our image, 2 methods; to open and close the popup, an event handler to call our close method and some extra code in our constructor. Let’s start with the property:

public string Image
{
            set
            {
                MyImageDetails.Source = new BitmapImage(new Uri(value, UriKind.Relative));
            }
}

Here I am referencing MyImageDetails, aka the image control on our DetailsView page. I’m setting its source by creating a new BitMapImage, based on my setter. You’ll notice as you complete typing BitMapImage that intellisense does not recognize it. The reason for this is that you need to add a reference to this namespace, by adding:

using System.Windows.Media.Imaging;

to the top of your DetailsView.xam.cs page. I’m setting the UriKind to relative, since I’m using an image within my image folder. If you were using an image retrieved from a database or xml feed, you would set this as absolute. I found this out the hard way, so take that as a pearl of wisdom. Let’s add our 2 methods:

public void Close()
{
            ImagePopUp.IsOpen = false;
            this.Visibility = System.Windows.Visibility.Collapsed;
}

public void Show()
{
            ImagePopUp.IsOpen = true;
            this.Visibility = System.Windows.Visibility.Visible;
            btnClosePopup.Focus();
            Page page = new Page();
            MyImageDetails.Source = page.MyImagePage.Source;
}

Now we’ll add our event handler for our close button:

private void btnClosePopup_Click(object sender, System.Windows.RoutedEventArgs e)
{
           this.Close();
}

This event handler calls our Close method we added earlier. What the method does is set the popup IsOpen property to false and changing its visibility to collapsed, thus closing the popup window. The Show method sets our IsOpen property to true, changes the visibility to visible, assigns focus to the Close button, and then instantiates our Page.xaml. Now we can reference the image control on our Page.xaml and assign it to our image control on our DetailsView.xaml page. Right, now we go back to our event handler on our Image_MouseLeftButtonDown event and add the following code:

myDetailsView.Show();

This code references our DetailsView control and calls its Show method. Finally, let’s go back to our DetailsView.xaml.cs page, and add some code to adjust the height and width of our popup window, to ensure that the popup displays in the center of our browser window:

App.Current.Host.Content.Resized += (s, e) =>
{
          ImageInfo.Width = App.Current.Host.Content.ActualWidth;
          ImageInfo.Height = App.Current.Host.Content.ActualHeight;
};

Almost finished. Now we add a listener to our DetailsView constructor:

btnClosePopup.Click += new System.Windows.RoutedEventHandler(btnClosePopup_Click);

Finally, we code our event handler on our Image_MouseLeftButtonDown on Page.xaml.cs:

private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
           myDetailsView.Show();
}

Now let’s built our solution and run it. When you click on the image, a popup window opens and the image is passed to our popup
window. Nice and simple.

You may download the source code here.