Permalink
Fetching contributors…
Cannot retrieve contributors at this time
462 lines (257 sloc) 31.6 KB
title ms.custom ms.date ms.prod ms.reviewer ms.suite ms.technology ms.tgt_pltfrm ms.topic helpviewer_keywords ms.assetid caps.latest.revision author ms.author manager
Walkthrough: My first WPF desktop application
03/30/2017
.net-framework
dotnet-wpf
article
getting started, WPF
WPF, getting started
b96bed40-8946-4285-8fe4-88045ab854ed
71
dotnet-bot
dotnetcontent
wpickett

Walkthrough: My first WPF desktop application

This walkthrough provides an introduction to the development of a [!INCLUDETLA#tla_wpf] application that includes the elements that are common to most [!INCLUDETLA2#tla_wpf] applications: [!INCLUDETLA#tla_xaml] markup, code-behind, application definitions, controls, layout, data binding, and styles.

This walkthrough guides you through the development of a simple [!INCLUDETLA2#tla_wpf] application using the following steps.

  • Defining [!INCLUDETLA2#tla_xaml] to design the appearance of the application's [!INCLUDETLA#tla_ui].

  • Writing code to build the application's behavior.

  • Creating an application definition to manage the application.

  • Adding controls and creating the layout to compose the application [!INCLUDETLA2#tla_ui].

  • Creating styles to create a consistent appearance throughout an application's [!INCLUDETLA2#tla_ui].

  • Binding the [!INCLUDETLA2#tla_ui] to data to both populate the [!INCLUDETLA2#tla_ui] from data and keep the data and [!INCLUDETLA2#tla_ui] synchronized.

By the end of the walkthrough, you will have built a standalone [!INCLUDETLA#tla_mswin] application that allows users to view expense reports for selected people. The application will be composed of several [!INCLUDETLA2#tla_wpf] pages that are hosted in a browser-style window.

The sample code that is used to build this walkthrough is available for both [!INCLUDETLA#tla_visualb] and [!INCLUDETLA#tla_cshrp] at Introduction to Building WPF Applications.

Prerequisites

For more information about installing the latest version of Visual Studio, see Install Visual Studio.

Creating the application project

In this section, you create the application infrastructure, which includes an application definition, two pages, and an image.

  1. Create a new WPF Application project in Visual Basic or Visual C# named ExpenseIt. For more information, see How to: Create a New WPF Application Project.

    [!NOTE] This walkthrough uses the xref:System.Windows.Controls.DataGrid control that is available in the .NET Framework 4. Be sure that your project targets the .NET Framework 4 or later. For more information, seeHow to: Target a Version of the .NET Framework.

  2. Open Application.xaml (Visual Basic) or App.xaml (C#).

    This [!INCLUDETLA2#tla_xaml] file defines a [!INCLUDETLA2#tla_wpf] application and any application resources. You also use this file to specify the [!INCLUDETLA2#tla_ui] that automatically shows when the application starts; in this case, MainWindow.xaml.

    Your [!INCLUDETLA2#tla_xaml] should look like this in Visual Basic:

    [!code-xamlExpenseIt#1_A]

    Or like this in C#:

    [!code-xamlExpenseIt#1]

  3. Open MainWindow.xaml.

    This [!INCLUDETLA2#tla_xaml] file is the main window of your application and displays content created in pages. The xref:System.Windows.Window class defines the properties of a window, such as its title, size, or icon, and handles events, such as closing or hiding.

  4. Change the xref:System.Windows.Window element to a xref:System.Windows.Navigation.NavigationWindow.

    This application will navigate to different content depending on the user interaction. Therefore, the main xref:System.Windows.Window needs to be changed to a xref:System.Windows.Navigation.NavigationWindow. xref:System.Windows.Navigation.NavigationWindow inherits all the properties of xref:System.Windows.Window. The xref:System.Windows.Navigation.NavigationWindow element in the XAML file creates an instance of the xref:System.Windows.Navigation.NavigationWindow class. For more information, see Navigation Overview.

  5. Change the following properties on the xref:System.Windows.Navigation.NavigationWindow element:

    • Set the xref:System.Windows.Window.Title%2A property to "ExpenseIt".

    • Set the xref:System.Windows.FrameworkElement.Width%2A property to 500 pixels.

    • Set the xref:System.Windows.FrameworkElement.Height%2A property to 350 pixels.

    • Remove the xref:System.Windows.Controls.Grid elements between the xref:System.Windows.Navigation.NavigationWindow tags.

    Your [!INCLUDETLA2#tla_xaml] should look like this in Visual Basic:

    [!code-xamlExpenseIt#2_A]

    Or like this in C#:

    [!code-xamlExpenseIt#2]

  6. Open MainWindow.xaml.vb or MainWindow.xaml.cs.

    This file is a code-behind file that contains code to handle the events declared in MainWindow.xaml. This file contains a partial class for the window defined in XAML.

  7. If you are using C#, change the MainWindow class to derive from xref:System.Windows.Navigation.NavigationWindow.

    In Visual Basic, this happens automatically when you change the window in XAML.

    Your code should look like this.

    [!code-csharpExpenseIt#3] [!code-vbExpenseIt#3]

Adding files to the application

In this section, you add two pages and an image to the application.

  1. Add a new Page (WPF) to the project named ExpenseItHome.xaml. For more information, see How to: Add New Items to a WPF Project.

    This page is the first page that is displayed when the application is launched. It will show a list of people from which a user can select a person to show an expense report for.

  2. Open ExpenseItHome.xaml.

  3. Set the xref:System.Windows.Controls.Page.Title%2A to "ExpenseIt - Home".

    Your [!INCLUDETLA2#tla_xaml] should look like this in Visual Basic:

    [!code-xamlExpenseIt#6_A]

    Or this in C#:

    [!code-xamlExpenseIt#6]

  4. Open MainWindow.xaml.

  5. Set the xref:System.Windows.Navigation.NavigationWindow.Source%2A property on the xref:System.Windows.Navigation.NavigationWindow to "ExpenseItHome.xaml".

    This sets ExpenseItHome.xaml to be the first page opened when the application starts. Your [!INCLUDETLA2#tla_xaml] should look like this in Visual Basic:

    [!code-xamlExpenseIt#7_A]

    Or this in C#:

    [!code-xamlExpenseIt#7]

  6. Add a new Page (WPF) to the project named ExpenseReportPage.xaml.

    This page will show the expense report for the person that is selected on ExpenseItHome.xaml.

  7. Open ExpenseReportPage.xaml.

  8. Set the xref:System.Windows.Controls.Page.Title%2A to "ExpenseIt - View Expense".

    Your [!INCLUDETLA2#tla_xaml] should look like this in Visual Basic:

    [!code-xamlExpenseIt#4_A]

    Or this in C#:

    [!code-xamlExpenseIt#4]

  9. Open ExpenseItHome.xaml.vb and ExpenseReportPage.xaml.vb, or ExpenseItHome.xaml.cs and ExpenseReportPage.xaml.cs.

    When you create a new Page file, Visual Studio automatically creates a code behind file. These code-behind files handle the logic for responding to user input.

    Your code should look like this.

    [!code-csharpExpenseIt#2_5] [!code-vbExpenseIt#2_5]

    [!code-csharpExpenseIt#5] [!code-vbExpenseIt#5]

  10. Add an image named watermark.png to the project. You can either create your own image, or copy the file from the sample code. For more information, see NIB:How to: Add Existing Items to a Project.

Building and running the application

In this section, you build and run the application.

  1. Build and run the application by pressing F5 or select Start Debugging from the Debug menu.

    The following illustration shows the application with the xref:System.Windows.Navigation.NavigationWindow buttons.

    ExpenseIt sample screen shot

  2. Close the application to return to [!INCLUDEvsprvs].

Creating the layout

Layout provides an ordered way to place [!INCLUDETLA2#tla_ui] elements, and also manages the size and position of those elements when a [!INCLUDETLA2#tla_ui] is resized. You typically create a layout with one of the following layout controls:

  • xref:System.Windows.Controls.Canvas

  • xref:System.Windows.Controls.DockPanel

  • xref:System.Windows.Controls.Grid

  • xref:System.Windows.Controls.StackPanel

  • xref:System.Windows.Controls.VirtualizingStackPanel

  • xref:System.Windows.Controls.WrapPanel

Each of these layout controls supports a special type of layout for its child elements. ExpenseIt pages can be resized, and each page has elements that are arranged horizontally and vertically alongside other elements. Consequently, the xref:System.Windows.Controls.Grid is the ideal layout element for the application.

[!NOTE] For more information about xref:System.Windows.Controls.Panel elements, see Panels Overview. For more information about layout, see Layout.

In the section, you create a single-column table with three rows and a 10-pixel margin by adding column and row definitions to the xref:System.Windows.Controls.Grid in ExpenseItHome.xaml.

  1. Open ExpenseItHome.xaml.

  2. Set the xref:System.Windows.FrameworkElement.Margin%2A property on the xref:System.Windows.Controls.Grid element to "10,0,10,10" which corresponds to left, top, right and bottom margins.

  3. Add the following [!INCLUDETLA2#tla_xaml] between the xref:System.Windows.Controls.Grid tags to create the row and column definitions.

    [!code-xamlExpenseIt#8]

    The xref:System.Windows.Controls.RowDefinition.Height%2A of two rows is set to xref:System.Windows.GridLength.Auto%2A which means that the rows will be sized base on the content in the rows. The default xref:System.Windows.Controls.RowDefinition.Height%2A is xref:System.Windows.GridUnitType.Star sizing, which means that the row will be a weighted proportion of the available space. For example if two rows each have a height of "*", they will each have a height that is half of the available space.

    Your xref:System.Windows.Controls.Grid should now look like the following XAML:

    [!code-xamlExpenseIt#9]

Adding controls

In this section, the home page [!INCLUDETLA2#tla_ui] is updated to show a list of people that users can select from to show the expense report for a selected person. Controls are UI objects that allow users to interact with your application. For more information, see Controls.

To create this [!INCLUDETLA2#tla_ui], the following elements are added to ExpenseItHome.xaml:

  • xref:System.Windows.Controls.ListBox (for the list of people).

  • xref:System.Windows.Controls.Label (for the list header).

  • xref:System.Windows.Controls.Button (to click to view the expense report for the person that is selected in the list).

Each control is placed in a row of the xref:System.Windows.Controls.Grid by setting the xref:System.Windows.Controls.Grid.Row%2A?displayProperty=nameWithType attached property. For more information about attached properties, see Attached Properties Overview.

  1. Open ExpenseItHome.xaml.

  2. Add the following [!INCLUDETLA2#tla_xaml] between the xref:System.Windows.Controls.Grid tags.

    [!code-xamlExpenseIt#10]

  3. Build and run the application.

The following illustration shows the controls that are created by the XAML in this section.

ExpenseIt sample screen shot

Adding an image and a title

In this section, the home page [!INCLUDETLA2#tla_ui] is updated with an image and a page title.

  1. Open ExpenseItHome.xaml.

  2. Add another column to the xref:System.Windows.Controls.Grid.ColumnDefinitions%2A with a fixed xref:System.Windows.Controls.ColumnDefinition.Width%2A of 230 pixels.

    [!code-xamlExpenseIt#11]

  3. Add another row to the xref:System.Windows.Controls.Grid.RowDefinitions%2A.

    [!code-xamlExpenseIt#11b]

  4. Move the controls to the second column by setting xref:System.Windows.Controls.Grid.Column%2A?displayProperty=nameWithType to 1. Move each control down a row, by increasing the xref:System.Windows.Controls.Grid.Row%2A?displayProperty=nameWithType by 1.

    [!code-xamlExpenseIt#12]

  5. Set the xref:System.Windows.Controls.Panel.Background%2A of the xref:System.Windows.Controls.Grid to be the watermark.png image file.

    [!code-xamlExpenseIt#14]

  6. Before the xref:System.Windows.Controls.Border, add a xref:System.Windows.Controls.Label with the content "View Expense Report" to be the title of the page.

    [!code-xamlExpenseIt#13]

  7. Build and run the application.

The following illustration shows the results of this section.

ExpenseIt sample screen shot

Adding code to handle events

  1. Open ExpenseItHome.xaml.

  2. Add a xref:System.Windows.Controls.Primitives.ButtonBase.Click event handler to the xref:System.Windows.Controls.Button element. For more information, see How to: Create a Simple Event Handler.

    [!code-xamlExpenseIt#15]

  3. Open ExpenseItHome.xaml.vb or ExpenseItHome.xaml.cs.

  4. Add the following code to the xref:System.Windows.Controls.Primitives.ButtonBase.Click event handler, which causes the window to navigate to the ExpenseReportPage.xaml file.

    [!code-csharpExpenseIt#16] [!code-vbExpenseIt#16]

Creating the UI for ExpenseReportPage

ExpenseReportPage.xaml displays the expense report for the person that was selected on the ExpenseItHome.xaml. This section adds controls and creates the [!INCLUDETLA2#tla_ui] for ExpenseReportPage.xaml. This section also adds background and fill colors to the various [!INCLUDETLA2#tla_ui] elements.

  1. Open ExpenseReportPage.xaml.

  2. Add the following XAML between the xref:System.Windows.Controls.Grid tags.

    This UI is similar to the UI created on ExpenseItHome.xaml except the report data is displayed in a xref:System.Windows.Controls.DataGrid.

    [!code-xamlExpenseIt#17]

  3. Build and run the application.

    [!NOTE] If you get an error that the xref:System.Windows.Controls.DataGrid was not found or does not exist, make sure that your project targets the .NET Framework 4 or later. For more information, see How to: Target a Version of the .NET Framework.

  4. Click the View button.

    The expense report page appears.

The following illustration shows the [!INCLUDETLA2#tla_ui] elements added to ExpenseReportPage.xaml. Notice that the back navigation button is enabled.

ExpenseIt sample screen shot

Styling controls

The appearance of various elements can often be the same for all elements of the same type in a [!INCLUDETLA2#tla_ui]. [!INCLUDETLA2#tla_ui] uses styles to make appearances reusable across multiple elements. The reusability of styles helps to simplify [!INCLUDETLA2#tla_xaml] creation and management. For more information about styles, see Styling and Templating. This section replaces the per-element attributes that were defined in previous steps with styles.

  1. Open Application.xaml or App.xaml.

  2. Add the following XAML between the xref:System.Windows.Application.Resources%2A?displayProperty=nameWithType tags:

    [!code-xamlExpenseIt#18]

    This [!INCLUDETLA2#tla_xaml] adds the following styles:

    • headerTextStyle: To format the page title xref:System.Windows.Controls.Label.

    • labelStyle: To format the xref:System.Windows.Controls.Label controls.

    • columnHeaderStyle: To format the xref:System.Windows.Controls.Primitives.DataGridColumnHeader.

    • listHeaderStyle: To format the list header xref:System.Windows.Controls.Border controls.

    • listHeaderTextStyle: To format the list header xref:System.Windows.Controls.Label.

    • buttonStyle: To format the xref:System.Windows.Controls.Button on ExpenseItHome.xaml.

    Notice that the styles are resources and children of the xref:System.Windows.Application.Resources%2A?displayProperty=nameWithType property element. In this location, the styles are applied to all the elements in an application. For an example of using resources in a [!INCLUDETLA2#tla_winfx] application, see Use Application Resources.

  3. Open ExpenseItHome.xaml.

  4. Replace everything between the xref:System.Windows.Controls.Grid elements with the following XAML.

    [!code-xamlExpenseIt#19]

    The properties such as xref:System.Windows.VerticalAlignment and xref:System.Windows.Media.FontFamily that define the look of each control are removed and replaced by applying the styles. For example, the headerTextStyle is applied to the "View Expense Report" xref:System.Windows.Controls.Label.

  5. Open ExpenseReportPage.xaml.

  6. Replace everything between the xref:System.Windows.Controls.Grid elements with the following XAML.

    [!code-xamlExpenseIt#20]

    This adds styles to the xref:System.Windows.Controls.Label and xref:System.Windows.Controls.Border elements.

  7. Build and run the application.

    After adding the [!INCLUDETLA2#tla_xaml] in this section, the application looks the same as it did before being updated with styles.

Binding data to a control

In this section, you create the [!INCLUDETLA#tla_xml] data that is bound to various controls.

  1. Open ExpenseItHome.xaml.

  2. After the opening xref:System.Windows.Controls.Grid element, add the following XAML to create an xref:System.Windows.Data.XmlDataProvider that contains the data for each person.

    The data is created as a xref:System.Windows.Controls.Grid resource. Normally this would be loaded as a file, but for simplicity the data is added inline.

    [!code-xamlExpenseIt#21]
    [!code-xamlExpenseIt#23]
    [!code-xamlExpenseIt#22]

  3. In the xref:System.Windows.Controls.Grid resource, add the following xref:System.Windows.DataTemplate, which defines how to display the data in the xref:System.Windows.Controls.ListBox. For more information about data templates, see Data Templating Overview.

    [!code-xamlExpenseIt#21]
    [!code-xamlExpenseIt#24]
    [!code-xamlExpenseIt#22]

  4. Replace the existing xref:System.Windows.Controls.ListBox with the following XAML.

    [!code-xamlExpenseIt#25]

    This XAML binds the xref:System.Windows.Controls.ItemsControl.ItemsSource%2A property of the xref:System.Windows.Controls.ListBox to the data source and applies the data template as the xref:System.Windows.Controls.ItemsControl.ItemTemplate%2A.

Connecting data to controls

In this section, you write the code that retrieves the current item that is selected in the list of people on the ExpenseItHome.xaml page, and passes its reference to the constructor of ExpenseReportPage during instantiation. ExpenseReportPage sets its data context with the passed item, which is what the controls defined in ExpenseReportPage.xaml will bind to.

  1. Open ExpenseReportPage.xaml.vb or ExpenseReportPage.xaml.cs.

  2. Add a constructor that takes an object so you can pass the expense report data of the selected person.

    [!code-csharpExpenseIt#26] [!code-vbExpenseIt#26]

  3. Open ExpenseItHome.xaml.vb or ExpenseItHome.xaml.cs.

  4. Change the xref:System.Windows.Controls.Primitives.ButtonBase.Click event handler to call the new constructor passing the expense report data of the selected person.

    [!code-csharpExpenseIt#27] [!code-vbExpenseIt#27]

Styling data with data templates

In this section, you update the [!INCLUDETLA2#tla_ui] for each item in the data bound lists by using data templates.

  1. Open ExpenseReportPage.xaml.

  2. Bind the content of the "Name" and "Department" xref:System.Windows.Controls.Label elements to the appropriate data source property. For more information about data binding, see Data Binding Overview.

    [!code-xamlExpenseIt#31]

  3. After the opening xref:System.Windows.Controls.Grid element, add the following data templates, which define how to display the expense report data.
    [!code-xamlExpenseIt#30]

  4. Apply the templates to the xref:System.Windows.Controls.DataGrid columns that display the expense report data.

    [!code-xamlExpenseIt#32]

  5. Build and run the application.

  6. Select a person and click the View button.

The following illustration shows both pages of the ExpenseIt application with controls, layout, styles, data binding, and data templates applied.

ExpenseIt sample screen shots

Best practices

This sample demonstrates a specific feature of WPF and, consequently, does not follow application development best practices. For comprehensive coverage of [!INCLUDETLA2#tla_winclient] and the [!INCLUDETLA2#tla_winfx] application development best practices, see the following topics as appropriate:

What's next

You now have a number of techniques at your disposal for creating a [!INCLUDETLA2#tla_ui] using [!INCLUDETLA#tla_winclient]. You should now have a broad understanding of the basic building blocks of a data-bound [!INCLUDETLA2#tla_winfx] application. This topic is by no means exhaustive, but hopefully you also now have a sense of some of the possibilities you might discover on your own beyond the techniques in this topic.

For more information about the WPF architecture and programming models, see the following topics:

For more information about creating applications, see the following topics:

See also

Panels Overview
Data Templating Overview
Building a WPF Application
Styles and Templates