Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

17
Building Windows Presentation Foundation Applications - C# - Part 1 Microsoft ® Virtual Labs

Transcript of Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Page 1: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Microsoft® Virtual Labs

Page 2: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Table of Contents

Building Windows Presentation Foundation Applications - C# - Part 1 ................................. 1

Exercise 1 Creating a WPF Application ........................................................................................................................ 2

Exercise 2 Data Binding to a Collection Object .......................................................................................................... 13

Lab Summary .............................................................................................................................................................. 15

Page 3: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Page 1 of 15

Building Windows Presentation Foundation

Applications - C# - Part 1

Objectives After completing this lab, you will be better able to:

� Develop a basic WPF application

� Use a NavigationWindow and page functions to create a wizard

� Learn how Property Bags are used

� Data bind to a collections object

Estimated Time to Complete This Lab

45 Minutes

Computer to Use Vista

Page 4: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Page 2 of 15

Exercise 1 Creating a WPF Application

Scenario There are two main types of applications you can build using the Windows Presentation Foundation: Installed

applications and Web Browser applications. The main differences between the types are in how they are hosted,

what security restrictions they must operate under, what application object they are associated with, and whether

they allow you to navigate from page to page. Each type of application has a corresponding Microsoft Visual Studio

2005 template that you can use to start implementing the application. In this lab, we will create an Installed

application. These applications are installed on the user's system with ClickOnce or MSI and hosted in a standalone

window. They have full access to the user's system resources and must have user’s consent before they can be

deployed.

In this exercise, you will develop a basic Address Book application with minimal functionality. You will learn how

to create basic UI, use Property Bags to pass information from one page to another, and write some application

logic. The application UI will show multiple examples of how to trigger the creation of a contact: via menu items,

context menu items, and toolbar buttons.

You will be able to find codes snippets used for this exercise under C:\Microsoft Hands-On Labs\DEV007

Building WPF Applications\codesnippets\CSharp\Exercise 1 Task 1 & Exercise 1 Task 2. The bolded codes in

the code section are the changes you need to make in your code.

Tasks Detailed Steps

Complete the following 2

tasks on:

Vista

1. Create a basic

application

a. Launch Microsoft Visual Studio 2005.

b. Create a new project using the C# “Windows Application (WPF)” project template

in Visual C# Net Framework 3.0. Name it ‘AddressBook’. This will create the

skeleton for our installed application.

c. The Address Book application will help you manage your Contacts. Add a new C#

class to your project. You can do this via the Solution Explorer by right-clicking

on the ‘AddressBook’ project, then choosing Add ���� New Item and then

selecting ‘Class’ from the dialog. We’ll call it Contact.cs and this will have our

data model: Code Snippet (code1.txt)

using System;

using System.Collections.Generic;

using System.Text;

using System.Windows.Data;

using System.Collections.ObjectModel;

namespace AddressBook

{

/// <summary>

/// Contact value object

/// </summary>

public class Contact

{

private String firstName;

private String lastName;

private String emailAddress;

private Uri homePageUri;

Page 5: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Page 3 of 15

Tasks Detailed Steps

private string homeAddress;

private string businessAddress;

/// <summary>

/// First name of contact

/// </summary>

public String FirstName

{

get { return firstName; }

set { firstName = value; }

}

/// <summary>

/// Last name of contact

/// </summary>

public String LastName

{

get { return lastName; }

set { lastName = value; }

}

/// <summary>

/// Email address of contact

/// </summary>

public String EmailAddress

{

get { return emailAddress; }

set { emailAddress = value; }

}

/// <summary>

/// Home page

/// </summary>

public Uri HomePage

{

get { return homePageUri; }

set { homePageUri = value; }

}

/// <summary>

/// Home address

/// </summary>

public string HomeAddress

{

get { return homeAddress; }

set { homeAddress = value; }

}

Page 6: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Page 4 of 15

Tasks Detailed Steps

/// <summary>

/// Business address

/// </summary>

public string BusinessAddress

{

get { return businessAddress; }

set { businessAddress = value; }

}

}

/// <summary>

/// This collection will hold all of our contacts in

the

/// address book

/// </summary>

public class ContactList :

ObservableCollection<Contact>

{

public ContactList()

: base()

{

}

}

}

Note: You will notice that the ContactList class derives from

ObservableCollection<T> and thus provides the main data context with a bindable

data collection. The DataContext property on an element is used to specify the source

data for the binding. By binding to data grouped into collections using WPF data

collections features, your application can automatically respond to changes in

individual data items in the collection as well as to changes in the collection as a

whole. Alternate views on data collections can be constructed to support sorting,

filtering, and navigating over the collection, without necessarily modifying the content

of the collection. The ObservableCollection<T> class is Windows Presentation

Foundation’s built-in implementation of a data collection. Exercise 2 will focus on our

data binding implementation.

d. Now let’s define a set of contacts. You will need to add a new text file to your

project and call it contacts.txt. You can do this via the Solution Explorer by right-

clicking on the project, then choosing Add ���� New Item and then selecting ‘Text

File’ from the dialog. Copy the following content over to that file: Code Snippet

(code2.txt)

Joe;Developer;[email protected];http://spaces.msn.com;1

North First St, Redmond, WA 98052; 2 South First St,

Redmond, WA 98052

Jane;Tester;[email protected];http://spaces.msn.com;101

Baker St, Bellevue, WA 98055; 202 Smith St, Redmond, WA

98052

Note: The contact information consists of two entries each on a separate line. Once

the contacts.txt file is created, select it in the Solution Explorer. Its properties should

Page 7: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Page 5 of 15

Tasks Detailed Steps

show up in the Properties window below. If they do not show up, right-click the file

and select Properties. Notice that the Build Action property has the value ‘Content’.

This tells the WPF MSBuild system to treat this file as loose content accompanying the

application. The Copy to Output Directory property has the value ‘Do not copy’.

Change this to ‘Copy if newer’. This will ensure that the contacts.txt file is copied

over to the build’s output directory if changes are made to it.

Figure 1.1 Properties for loose content file contacts.txt

e. To allow us to have more control over what happens when the application starts

and exits, we will handle the Application Startup and Exit events. Add the

following code to App.xaml.cs: Code Snippet (code3.txt)

public App()

{

}

void AppStartup(object sender, StartupEventArgs args)

{

Window1 mainWindow = new Window1();

mainWindow.WindowStartupLocation =

WindowStartupLocation.CenterScreen;

mainWindow.Show();

}

private void AppExit(Object sender, ExitEventArgs e)

{

}

f. Double click on MyApp.xaml to view the XAML and add the following markup

to MyApp.xaml so that the Startup event is wired up to the code. You will also

need to remove the StartupUri property so that the Startup event code can handle

the loading of Window1. Code Snippet (code4.txt)

<Application

Page 8: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Page 6 of 15

Tasks Detailed Steps

x:Class="AddressBook.App"

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

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presen

tation"

StartupUri="Window1.xaml"

Startup="AppStartup"

Exit="AppExit" >

<Application.Resources>

</Application.Resources>

</Application>

g. Let’s create a basic UI. The UI will consist of a Window with a Grid which in

turn contains a DockPanel for each of the following: the menu bar, the toolbar, the

status bar, and the left-pane which lists your contacts. A frame on the right will

house the details information for the selected contact. In the Window1.xaml file,

we’ll start with a Grid and name it DocumentRoot: When you double click on

Window1.xaml, you will see xaml tab below along with Code and Design tab.

Click on XAML Tab to edit xaml Code Snippet (code5.txt)

<Window x:Class="AddressBook.Window1"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presen

tation"

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

Title="AddressBook"

Loaded="WindowLoaded"

SizeToContent="WidthAndHeight"

MinWidth="640"

MinHeight="480">

<Grid Background="White" Name="DocumentRoot">

<Grid.ColumnDefinitions>

<ColumnDefinition Width="200"/>

<ColumnDefinition Width="*"/>

</Grid.ColumnDefinitions>

<Grid.RowDefinitions>

<RowDefinition Height="Auto"/>

<RowDefinition Height="Auto"/>

<RowDefinition Height="*"/>

<RowDefinition Height="Auto"/>

</Grid.RowDefinitions>

<!-- Menu -->

<!-- Tool Bar -->

<!-- Content Area -->

<!-- Status Bar -->

</Grid>

</Window>

h. All of our layout and form elements will be within the DocumentRoot Grid. Next,

create the DockPanel_Menu which will enclose the menu bar. We will have two

top-level MenuItems: File and Edit, each with several child MenuItems. Code

Snippet (code6.txt)

Page 9: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Page 7 of 15

Tasks Detailed Steps

<!-- Menu Bar -->

<DockPanel

Name="DockPanel_Menu"

Grid.Column="0"

Grid.ColumnSpan="2"

Grid.Row="0">

<Menu Background="White">

<MenuItem Header="File">

<MenuItem Header="New Contact"

Click="LaunchNewContactWizard"/>

<MenuItem Header="New Group"

Click="NotImplementedMsg"/>

<Separator />

<MenuItem Header="Properties"

Click="NotImplementedMsg"/>

<MenuItem Header="Delete"

Click="NotImplementedMsg"/>

<MenuItem Header="Import">

<MenuItem Header="Address book (WAB)..."

Click="NotImplementedMsg"/>

<MenuItem Header="Business card vCard)..."

Click="NotImplementedMsg"/>

</MenuItem>

<Separator />

<MenuItem Header="Exit" InputGestureText="Alt-F4"

Click="ExitApplication">

<MenuItem.ToolTip>

<ToolTip>

Click here to exit

</ToolTip>

</MenuItem.ToolTip>

</MenuItem>

</MenuItem>

</Menu>

<Menu Background="White">

<MenuItem Header="Edit">

<MenuItem Command="ApplicationCommands.Copy"/>

<MenuItem Command="ApplicationCommands.Paste"/>

</MenuItem>

</Menu>

</DockPanel>

i. The tool bar comes next. The ToolBar has two Buttons which allow you to add

and remove contacts. We’ll implement the add functionality later. The delete

function is a placeholder and is handled by the NotImplementedMsg handler

method we’ve previously defined. Code Snippet (code7.txt)

<!-- Tool Bar -->

<DockPanel

Name="DockPanel_Toolbar"

Grid.Column="0"

Grid.ColumnSpan="2"

Grid.Row="1">

<ToolBar>

Page 10: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Page 8 of 15

Tasks Detailed Steps

<Button Click="LaunchNewContactWizard" ToolTip="Add

Contact">

+

</Button>

<Button Click="NotImplementedMsg" ToolTip="Delete

Contact">

-

</Button>

</ToolBar>

</DockPanel>

j. The left pane of the Address Book application’s main window must display a list

of your contacts. For this purpose, we’ll use a ListBox, with each Contact’s

FirstName as a ListItem entry. For now, let’s focus on the ListBox and the

DockPanel which encloses it. We’ll come back to the ListItems when we look at

data binding.While we are at it, let us also define a Context Menu for the list of

contacts. This will allow you to Add a Contact or Add a Group. Code Snippet

(code8.txt)

<!-- Left Pane for contact list view -->

<DockPanel

Name="DockPanel_LeftPane"

Grid.Column="0"

Grid.Row="2">

<ListBox Name="allContacts"

SelectionChanged="ListItemSelected">

<ListBox.ContextMenu>

<ContextMenu>

<MenuItem Header="Add a Contact"

Click="LaunchNewContactWizard"/>

<MenuItem Header="Add a Group"

Click="NotImplementedMsg"/>

</ContextMenu>

</ListBox.ContextMenu>

</ListBox>

</DockPanel>

k. Another key element of the main window’s UI is the status bar. This is achieved

by enclosing a TextBlock within a StatusBar element. Code Snippet (code9.txt)

<!-- Status Bar -->

<DockPanel

Name="DockPanel_Statusbar"

Grid.Column="0"

Grid.ColumnSpan="2"

Grid.Row="3">

<StatusBar

BorderBrush="Black"

BorderThickness="1">

<TextBlock Name="tb" Foreground="Black">

Status bar

</TextBlock>

</StatusBar>

</DockPanel>

l. The final piece of the basic application UI is the right hand side frame. When the

Page 11: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Page 9 of 15

Tasks Detailed Steps

ListItems finally show up, clicking on one of them will display the contact’s

information in the Frame_RightPane. Code Snippet (code10.txt)

<!-- RightPanel -->

<Frame Name="Frame_RightPane"

Grid.Column="1"

Grid.Row="2"/>

m. Now that we've added the UI elements in the XAML page, it is time to move on to

the code-behind. In the Window1.xaml.cs file, add the ExitApplication,

NotImplementedMsg, WindowLoaded, ListItemSelected and

LaunchNewContactWizard methods in the body of the Window1 class. You will

notice that the latter 3 methods have empty bodies. We will add logic to these

methods later: Code Snippet (code11.txt)

//

// Triggered on Window load. Sets the ContactList

collection

// as the Data Context.

//

private void WindowLoaded(object sender,

RoutedEventArgs e)

{

}

//

// Triggers application shutdown

//

void ExitApplication(object sender,

RoutedEventArgs e)

{

this.Close();

}

//

// Shows a message box informing user that a

feature

// hasn't been implemented.

//

void NotImplementedMsg(object sender,

RoutedEventArgs e)

{

MessageBox.Show("This feature has not been

implemented.",

"Not Implemented");

}

//

// Triggered when an item in the Contacts list is

selected

//

void ListItemSelected(object sender,

SelectionChangedEventArgs args)

Page 12: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Page 10 of 15

Tasks Detailed Steps

{

}

//

// Triggered when context menu or other toolbar

option

// is clicked to launch

// 'Create a new contact' dialog

//

private void LaunchNewContactWizard(object sender,

RoutedEventArgs e)

{

}

n. Build and run your application. You now have the skeleton of your Address Book

application. Since we haven’t initialized and used the contact information, you

won't see anything in the left and right panes. At this stage, you application should

look like this:

Figure 1.2 Basic Address Book application UI

2. Use Property Bag to

store the collection

of Contacts

a. Upon startup, the application must read the contact information from a file and

initialize the ContactList object. Open the App.xaml.cs file for editing. The

ReadContactsFromFile method reads data from a file. In the class body, add this

method and the helper method to de-tokenize entries. Code Snippet (code1.txt)

//

// Reads contact information from file

//

private ContactList ReadContactsFromFile()

{

ContactList contactList = new ContactList();

Page 13: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Page 11 of 15

Tasks Detailed Steps

// Create an instance of StreamReader to read

from a file.

// The using statement also closes the

StreamReader.

using (StreamReader sr = new

StreamReader("contacts.txt"))

{

String line;

// Read and display lines from the file

until the

// end of the file is reached.

while ((line = sr.ReadLine()) != null)

{

contactList.Add(CreateContactFromLine(line));

}

}

return contactList;

}

//

// De-tokenize one line of contact information and

// hydrate a Contact object

//

private Contact CreateContactFromLine(string line)

{

string[] tokens = line.Split(new char[] { ';'

});

if (tokens.Length != 6)

{

throw new ApplicationException(

String.Format("Input contact file

format. " +

"Expected tokens {0}; Actual tokens

{1}", 6,

tokens.Length));

}

Contact contact = new Contact();

contact.FirstName = tokens[0];

contact.LastName = tokens[1];

contact.EmailAddress = tokens[2];

contact.HomePage =

(String.IsNullOrEmpty(tokens[3]) ?

null :

new Uri(tokens[3],

UriKind.Absolute));

contact.HomeAddress = tokens[4];

contact.BusinessAddress = tokens[5];

return contact;

}

Page 14: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Page 12 of 15

Tasks Detailed Steps

b. The ReadContactFromFile method uses System.IO.StreamReader. Make sure you

add a using statement for it before the namespace declaration: Code Snippet

(code2.txt)

using System.IO;

c. The ContactList data returned by the ReadContactsFromFile method is added as an

entry in the application’s Property Bag. Modify the AppStartup method as shown

below: Code Snippet (code3.txt)

//

// Triggered on application startup. Positions the

window,

// Initializes the contact list model and adds it

to the

// Property Bag.

//

void AppStartup(object sender, StartupEventArgs

args)

{

// initialize the Contacts collection using

data from file

ContactList contactList =

ReadContactsFromFile();

// add it to the Property Bag

this.Properties["ContactList"] = contactList;

Window1 mainWindow = new Window1();

// make sure the window appears in the center

of the screen

mainWindow.WindowStartupLocation =

WindowStartupLocation.CenterScreen;

mainWindow.Show();

}

d. While we are at it, let’s also create a method to save the changes back to the

contacts.txt file. The logic is pretty straightforward and not really related to this

lab, so we won’t go into it. Code Snippet (code4.txt)

//

// Persists changes from ContactList object in

Property Bag

// to file.

//

private void SaveContactsToFile(string fileName)

{

}

e. Build and run the application. It should still look like it did in Figure 1.2. From the

UI it does not appear we are making any progress. Rest easy, we are!

Page 15: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Page 13 of 15

Exercise 2 Data Binding to a Collection Object

Scenario WPF provides powerful data services which allow you to integrate data into your applications. UI elements can be

bound to data in CLR objects and XML sources. Data sources manage the relationship between data items (business

objects) and the various data binding capabilities of your application. There are several different types of data

sources for different source data types, including ObjectDataProvider and XmlDataProvider. Both implement the

IDataSource interface which provides a data source with the ability to notify its dependent bindings of changes to

the data object referred to by the data source.

In this exercise, you will learn how to data bind the contacts ListBox to the ContactsList collection present in the

property bag.

You will be able to find codes snippets used for this exercise under C:\Microsoft Hands-On Labs\DEV007

Building WPF Applications\codesnippets\CSharp\Exercise 2. The bolded codes in the code section are the

changes you need to make in your code.

Tasks Detailed Steps

Complete the following

task on:

Vista

1. Creating a one-way

binding

a. Define an ObjectDataProvider called “ContactList” as a resource in the

Resources section within the Window element in the Window1.xaml page. The

ObjectDataProvider’s type name is set to the namespace-qualified name of the

ContactList collection class. In addition, the name of the assembly, AddressBook,

is supplied to the MethodName attribute. Make sure you insert this

Window.Resources element above the Grid definition. When you double click on

Window1.xaml, you will see ‘Xaml’ tab below next to the ‘Design’ tab. Click on

‘Xaml’ tab to edit: Code Snippet (code1.txt)

<Window.Resources>

<ObjectDataProvider x:Key="ContactList"

MethodName="AddressBook.ContactList,AddressBook" />

</Window.Resources>

b. Styles allow an application, document, or user interface (UI) designer to

standardize on a particular look for their product. Further, data templates are used

to define the appearance of data. In order to style the UI for contact list data, you

must define a data template called “ContactNameTemplate” with a TextBlock

bound to the FirstName property of the Contact object in the ContactList. Code

Snippet (code2.txt)

<Window.Resources>

<ObjectDataProvider x:Key="ContactList"

MethodName="AddressBook.ContactList,AddressBook" />

<DataTemplate x:Key="ContactNameTemplate" >

<TextBlock Text="{Binding Path=FirstName}" />

</DataTemplate>

</Window.Resources>

Page 16: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Page 14 of 15

Tasks Detailed Steps

c. We are ready to specify the ItemsSource for the allContacts ListBox as well as

assign the ContactNameTemplate. Code Snippet (code3.txt)

<ListBox Name="allContacts"

SelectionChanged="ListItemSelected"

ItemsSource="{Binding }"

ItemTemplate="{DynamicResource ContactNameTemplate}"

IsSynchronizedWithCurrentItem="True">

<ListBox.ContextMenu>

<ContextMenu>

<MenuItem Header="Add a Contact"

Click="LaunchNewContactWizard"/>

<MenuItem Header="Add a Group"

Click="NotImplementedMsg"/>

</ContextMenu>

</ListBox.ContextMenu>

</ListBox>

d. All that’s left is to set the value of the DockPanel_LeftPane’s data context to the

ContactList entry in the Property Bag. Add this line to the WindowLoaded method

in Window1.xaml.cs. Code Snippet (code4.txt)

DockPanel_LeftPane.DataContext =

Application.Current.Properties["ContactList"];

e. Browse into the folder where you saved your project. If you have saved in default

directory. Please go to C:\Users\User\Documents\Visual Studio

2005\Projects\AddressBook\AddressBook. Copy contacts.txt into the directory

bin\debug of the project.

f. If a dialog appears click Yes to continue.

g. Build and run your application. You should now see the application load with your

list of contacts populated in the ListBox on the left pane.

Page 17: Microsoft Word - Building Windows Presentation Foundation Applications CSharp Part 1

Building Windows Presentation Foundation Applications - C# - Part 1

Page 15 of 15

Tasks Detailed Steps

Figure 1.3 Basic Address Book application UI

Lab Summary In part 1 and 2 of this lab you performed the following exercises:

� Created a WPF application

� Bound an application UI element to data in a collection object

� Used Windows and Page Functions to create a structured navigation wizard

In part 1 and 2 of this lab, you learned how to use the WPF application model, its layout system, and other features

to build a sample Address Book application. In three exercises you developed the use cases for:

� Creating a contact with personal information (name, email, URL, IM address etc.) and home/business contact

information.

� Navigating to the Add Contact wizard in various ways (via menu item, context menu item and toolbar button).

� Listing all contacts in the address book.

� Listing detail information on selected contact.

� Actions associated with a contact, namely, sending email or viewing their homepage.