Click to Rate and Give Feedback
MSDN
MSDN Library
.NET Development
.NET Framework 3.5
 Getting Started with Windows Presen...

  Switch on low bandwidth view
This page is specific to
Microsoft Visual Studio 2008/.NET Framework 3.5

Other versions are also available for the following:
Windows Presentation Foundation
Getting Started with Windows Presentation Foundation

This tutorial provides a simple introduction to the development of a Windows Presentation Foundation (WPF) application that includes the elements that are common to most WPF applications: Extensible Application Markup Language (XAML) markup, code-behind, application definitions, controls, layout, data binding, and styles.

This topic contains the following sections.

  • Summary
  • Prerequisites
  • Create the Application Code Files
  • Building and Running the Application
  • Add Layout
  • Add Controls
  • Add an Image and Title
  • Add Code to Handle Events
  • Create the UI for ExpenseReportPage
  • Add Code to Style a Control
  • Bind Data to a Control
  • Connect Data to Controls
  • Add Style to Data with Data Templates
  • Best Practices
  • What's Next
  • Related Topics

This tutorial guides you through the development of a simple WPF application using the following steps.

  • Defining XAML markup to design the appearance of the application's user interface (UI).

  • Writing code to build the application's behavior.

  • Creating an application definition to manage the application.

  • Adding controls and layout to compose the application UI.

  • Creating styles to create a consistent appearance throughout an application's UI.

  • Binding the UI to data to both populate the UI from data and keep the data and UI synchronized.

By the end of the tutorial, you will have built a standalone Windows application that allows users to view expense reports for selected people. The application will be composed of several WPF pages that are hosted in a browser-style window.

The sample code that is used to build this tutorial is available for both C# and Microsoft Visual Basic .NET; see Introduction to Building Windows Presentation Foundation Applications.

To build the application that is developed during this tutorial, you will need to have both the Microsoft .NET Framework and the Windows Software Development Kit (SDK) installed.

When these are installed, you can build the application from a command window (although you can use an Integrated Development Environment (IDE) like Microsoft Visual Studio if desired). To build from the command prompt, you need to use the command window that is installed with the Windows Software Development Kit (SDK). You can find this in the following menu location:

  • Start Menu | All Programs | Microsoft Windows SDK | CMD Shell

Alternatively, you can open the Windows command prompt using the following steps:

  1. From the Start menu, select Run.

  2. Enter the following:

    C:\WINDOWS\system32\cmd.exe /E:ON /V:ON /T:0E /K "C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin\SetEnv.Cmd"

  3. Press OK.

Note that SetEnv.cmd sets up the environment that you need to build WPF applications from the command prompt.

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

  1. Create a new XAML markup file called App.xaml. This file defines a WPF application, and you also use it to specify the UI to automatically show when the application starts; in this case, HomePage.xaml (created in the next step). Your XAML markup should look like this:

    <Application 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      StartupUri="HomePage.xaml">
    </Application>
    
  2. Create a new XAML markup file called HomePage.xaml, which will be the first page that is displayed when the application is launched. HomePage.xaml will show a list of people from which a user can select a person to show an expense report for. Add a Page element to HomePage.xaml, with the following configuration:

    • The title bar of the browser is "ExpenseIt".

    • The width of the browser is 550 device-independent pixels.

    • The height of the browser is 350 device-independent pixels.

    • The title of the page is "ExpenseIt - Home".

    Your XAML markup should look like this:

    <Page 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.HomePage"
      WindowTitle="ExpenseIt"
      Title="ExpenseIt - Home" 
      WindowWidth="550" WindowHeight="380">
    </Page>
    
  3. Create a new code file called HomePage.xaml.cs. This file will be a code-behind file that contains code to handle the events declared in HomePage.xaml. Your code should look like this:

    C#
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    namespace ExpenseIt
    {
        public partial class HomePage : Page
        {
            public HomePage()
            {
                InitializeComponent();
            }
        }
    }
    
  4. Create a new XAML markup file called ExpenseReportPage.xaml. Add a Page element and set "ExpenseIt - View Expense Report" as the page title. This page will show the expense report for the person that is selected on HomePage.xaml. Your XAML markup should look like this:

    <Page 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.ExpenseReportPage"
      Title="ExpenseIt - View Expense Report">
    </Page>
    
  5. Create a new file called it ExpenseReportPage.xaml.cs. This file will be a code-behind file that binds expense report data to the UI defined in ExpenseReportPage.xaml. Your code should look like this:

    C#
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    namespace ExpenseIt
    {
        public partial class ExpenseReportPage : Page
        {
            public ExpenseReportPage()
            {
                InitializeComponent();
            }
        }
    }
    
  6. Add an image called watermark.png to the same folder as the five code files that you created in the preceding steps. You can either create your own image, or copy the file of the same name from the sample code.

In this step, you use MSBuild to build the application that you defined in the previous section.

  1. Create a new file called ExpenseIt.csproj. This file will be the MSBuild file, which is a special XML file that contains the build configuration for your application and includes the following:

    • The global build variables for the compiled project, including the name of the built assembly, what type of assembly to build, and the folder to add the built assembly to.

    • References to the code files.

    • References to the Microsoft .NET Framework assemblies that contain the types that the application uses.

    The content of the build file should look like this:

    <?xml version="1.0" encoding="utf-8"?>
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <PropertyGroup>
            <AssemblyName>ExpenseIt</AssemblyName>
            <TargetType>winexe</TargetType>
            <OutputPath>bin\$(Configuration)\</OutputPath>
        </PropertyGroup>
        <ItemGroup>
            <Reference Include="System"/>
            <Reference Include="System.Xml"/>
            <Reference Include="System.Data"/>
            <Reference Include="WindowsBase"/>
            <Reference Include="PresentationCore"/>
            <Reference Include="PresentationFramework"/>
        </ItemGroup>
        <ItemGroup>
            <ApplicationDefinition Include="App.xaml"/>
            <Page Include="HomePage.xaml"/>
            <Compile Include="HomePage.xaml.cs" />
            <Page Include="ExpenseReportPage.xaml"/>
            <Compile Include="ExpenseReportPage.xaml.cs" />
            <Resource Include="watermark.png"/>
        </ItemGroup>
        <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets"/>
        <Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets"/>
    </Project>
    
  2. Open a command window to the same folder as your project file and application code files.

  3. From the command prompt, run the following command:

    MSBuild ExpenseIt.csproj

    For Microsoft Visual Basic .NET, run the following command instead:

    MSBuild ExpenseIt.vbproj

    To compile and run the application using Visual Studio, open the project file in Visual Studio and press F5.

NoteNote:

Visual Studio 2005 generates a project file automatically. Because this tutorial does not assume that Visual Studio is installed, the process for creating a project file is detailed. For more information on the creation of .csproj files, see Building a WPF Application (WPF). If you are using Visual Studio to complete this tutorial, overwrite the content of the generated .csproj file with the preceding MSBuild text.

  1. Open the folder that contains the built application executable: expenseit.exe. If built from the command prompt, expenseit.exe is located in the following folder:

    Folder Containing Application Code Files\bin\

    If built using Visual Studio, expenseit.exe is located in the following folder instead:

    Folder Containing Application Code Files\bin\debug\

  2. From the command prompt, run expenseit.exe. The following figure shows the running application.

    ExpenseIt sample screen shot

Layout provides an ordered way to place UI elements, and also manages the size and position of those elements when a UI is resized. You typically add layout to your UI with one of the following layout controls:

Each of these 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 Grid is the ideal layout element for the application.

NoteNote:

For more information on Panel elements, see Panels Overview.

The following XAML markup creates a single-column table with three rows and a 10-pixel margin by adding a Grid to HomePage.xaml:

  1. Open HomePage.xaml

  2. Add the following XAML between the Page tags.

    <Page 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.HomePage"
      WindowTitle="ExpenseIt"
      Title="ExpenseIt - Home" 
      WindowWidth="550" WindowHeight="380">
        <Grid Margin="10">
          <Grid.ColumnDefinitions>
            <ColumnDefinition />
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
            <RowDefinition Height="Auto" />
          </Grid.RowDefinitions>
        </Grid>
    </Page>
    

In this step, the home page UI is updated to show a list of people that users can select from to show the expense report for a selected person. To create this UI, the following elements are added to HomePage.xaml:

  • ListBox (for the list of people).

  • Label (for the list header).

  • Button (to click to view the expense report for the person that is selected in the list).

Use the following steps to update HomePage.xaml:

  1. Overwrite the contents of the HomePage.xaml file with the following XAML.

    <Page 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.HomePage"
      WindowTitle="ExpenseIt"
      Title="ExpenseIt - Home" 
      WindowWidth="550" WindowHeight="380">
    
      <Grid Margin="10">
    
        <Grid.ColumnDefinitions>
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition />
          <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
          
        <!-- People list -->
        <Border Grid.Column="0" Grid.Row="0" Height="35" Padding="5" Background="#4E87D4">
          <Label VerticalAlignment="Center" Foreground="White">Names</Label>
        </Border>
        <ListBox Name="peopleListBox" Grid.Column="0" Grid.Row="1">
          <ListBoxItem>Mike</ListBoxItem>
          <ListBoxItem>Lisa</ListBoxItem>
          <ListBoxItem>John</ListBoxItem>
          <ListBoxItem>Mary</ListBoxItem>
        </ListBox>
    
        <!-- View report button -->
        <Button Grid.Column="0" Grid.Row="2" Margin="0,10,0,0" Width="125"
          Height="25" HorizontalAlignment="Right">View</Button>
          
      </Grid>
    
    </Page>
    
  2. Compile and run the application.

The following image shows the controls that are created by the code in this step.

ExpenseIt sample screen shot

In this step, the home page UI is updated with an appropriate image, and a page title:

  1. Open HomePage.xaml.

  2. Overwrite the contents of the HomePage.xaml file with the following XAML.

    <Page 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.HomePage"
      WindowTitle="ExpenseIt"
      Title="ExpenseIt - Home" 
      WindowWidth="550" WindowHeight="380">
    
      <Grid>
        
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="230" />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition />
        </Grid.RowDefinitions>
    
        <DockPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0">
          <Canvas DockPanel.Dock="Left" Width="230" Height="100">
            <Image Source="watermark.png" />
          </Canvas>
          <Label VerticalAlignment="Center" FontFamily="Trebuchet MS" 
            FontWeight="Bold" FontSize="18" Foreground="#0066cc">
            View Expense Report
          </Label>
        </DockPanel>
    
        <Grid Margin="10" Grid.Column="1" Grid.Row="1">
    
          <Grid.ColumnDefinitions>
            <ColumnDefinition />
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
            <RowDefinition Height="Auto" />
          </Grid.RowDefinitions>
          
          <!-- People list -->
          <Border Grid.Column="0" Grid.Row="0" Height="35" Padding="5" Background="#4E87D4">
            <Label VerticalAlignment="Center" Foreground="White">Names</Label>
          </Border>
          <ListBox Name="peopleListBox" Grid.Column="0" Grid.Row="1">
            <ListBoxItem>Mike</ListBoxItem>
            <ListBoxItem>Lisa</ListBoxItem>
            <ListBoxItem>John</ListBoxItem>
            <ListBoxItem>Mary</ListBoxItem>
          </ListBox>
    
          <!-- View report button -->
          <Button Grid.Column="0" Grid.Row="2" Margin="0,10,0,0" Width="125" 
            Height="25" HorizontalAlignment="Right">View</Button>
    
        </Grid>
    
      </Grid>
    </Page>
    

    This XAML updates the Grid in the following ways:

    • Creating a new grid with two rows.

    • Adding a DockPanel with a Canvas, Image, and Label to the first row. The DockPanel spans the two columns of the first row which, in conjunction with the Canvas being docked to the left, enables the Label to overlap the Image.

    • Using the Source attribute of the Image element to specify the source image: watermark.png.

    • Adding the following title text to the Label: "View Expense Report".

    • Using the attributes of the Canvas and Label to configure their appearance and size.

    • Moving the grid that HomePage.xaml originally contained to the second column of the second row of the new grid.

  3. Compile and run the application.

The following figure shows the results of this step.

ExpenseIt sample screen shot
  1. Open HomePage.xaml.

  2. Overwrite the Button element defined in the previous step with the following code.

    ...
    <!-- View report button -->
    <Button Grid.Column="0" Grid.Row="2" Width="125" Height="25" 
      Margin="0,10,0,0" HorizontalAlignment="Right" 
      Click="viewButton_Click">View</Button>
    ...
    
    NoteNote:

    The name of the Button event to handle is Click. The name of the developer-defined event handler is viewButton_Click. The event handler is registered with the Click event for the Button control.

  3. Open the HomePage.xaml.cs that you created in the Create the Application Code Files step of the tutorial.

  4. Overwrite the contents of the file with the following code. This adds code to handle the Click event, which causes the ExpenseReportPage.xaml file to be navigated to.

    C#
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    namespace ExpenseIt
    {
        public partial class HomePage : Page
        {
            public HomePage()
            {
                InitializeComponent();
            }
            private void viewButton_Click(object sender, RoutedEventArgs args)
            {
                // View Expense Report
                ExpenseReportPage expenseReportPage = new ExpenseReportPage();
                this.NavigationService.Navigate(expenseReportPage);
            }
        }
    }
    

ExpenseReportPage.xaml displays the expense report for the person that was selected on the HomePage.xaml. The following updates add controls and layout to create the basic UI for ExpenseReportPage.xaml. They also add background and fill colors to the various UI elements.

  1. Open the ExpenseReportPage.xaml file and add the following code.

    <Page 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.ExpenseReportPage"
      Title="ExpenseIt - View Expense Report">
    
      <Grid>
    
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="230" />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition />
        </Grid.RowDefinitions>
    
        <DockPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0">
          <Canvas DockPanel.Dock="Left" Width="230" Height="100">
            <Image Source="watermark.png" />
          </Canvas>
          <Label VerticalAlignment="Center" FontFamily="Trebuchet MS" 
            FontWeight="Bold" FontSize="18" Foreground="#0066cc">
            Expense Report For:
          </Label>
        </DockPanel>
    
        <Grid Margin="10" Grid.Column="1" Grid.Row="1">
    
          <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition />
          </Grid.RowDefinitions>
    
          <!-- Name -->
          <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Orientation="Horizontal">
            <Label Margin="0,0,0,5" FontWeight="Bold">Name:</Label>
            <Label Margin="0,0,0,5" FontWeight="Bold"></Label>
          </StackPanel>
    
          <!-- Department -->
          <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" 
            Orientation="Horizontal">
            <Label Margin="0,0,0,5" FontWeight="Bold">Department:</Label>
            <Label Margin="0,0,0,5" FontWeight="Bold"></Label>
          </StackPanel>
    
          <Grid Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3">
    
            <Grid.ColumnDefinitions>
              <ColumnDefinition />
              <ColumnDefinition Width="10" />
              <ColumnDefinition />
            </Grid.ColumnDefinitions>
    
            <Grid.RowDefinitions>
              <RowDefinition Height="Auto" />
              <RowDefinition />
            </Grid.RowDefinitions>
    
            <!-- Expense type list -->
            <Border Grid.Column="0" Grid.Row="0" Height="35" Padding="5" Background="#4E87D4">
              <Label VerticalAlignment="Center" Foreground="White">Expense Type</Label>
            </Border>
            <ListBox Grid.Column="0" Grid.Row="1" />
    
            <!-- Amount list -->
            <Border Grid.Column="2" Grid.Row="0" Height="35" Padding="5" Background="#4E87D4">
              <Label VerticalAlignment="Center" Foreground="White">Amount</Label>
            </Border>
            <ListBox Grid.Column="2" Grid.Row="1" />
    
          </Grid>
        </Grid>
      </Grid>
    </Page>
    
  2. Compile and run the application.

The following image shows the UI elements added to ExpenseReportPage.xaml.

ExpenseIt sample screen shot

The appearance of various elements can often be the same for all elements of the same type in a UI. UI uses styles to make appearances reusable across multiple elements. The reusability of styles helps to simplify XAML markup creation and management. This step replaces the per-element attributes that were defined in previous steps with styles:

  1. Open the App.xaml file created in the Create the Application Code Files step of this tutorial.

  2. Overwrite the content of the file with the following XAML markup:

    <Application 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      StartupUri="HomePage.xaml">
    
      <Application.Resources>
    
        <!-- Background image style -->
        <Style x:Key="backgroundImageStyle">
          <Setter Property="Image.Source" Value="watermark.png"/>
        </Style>
    
        <!-- Header text style -->
        <Style x:Key="headerTextStyle">
          <Setter Property="Label.VerticalAlignment" Value="Center"></Setter>
          <Setter Property="Label.FontFamily" Value="Trebuchet MS"></Setter>
          <Setter Property="Label.FontWeight" Value="Bold"></Setter>
          <Setter Property="Label.FontSize" Value="18"></Setter>
          <Setter Property="Label.Foreground" Value="#0066cc"></Setter>
        </Style>
    
        <!-- Label style -->
        <Style x:Key="labelStyle" TargetType="{x:Type Label}">
          <Setter Property="VerticalAlignment" Value="Top" />
          <Setter Property="HorizontalAlignment" Value="Left" />
          <Setter Property="FontWeight" Value="Bold" />
          <Setter Property="Margin" Value="0,0,0,5" />
        </Style>
    
        <!-- List header style -->
        <Style x:Key="listHeaderStyle" TargetType="{x:Type Border}">
          <Setter Property="Height" Value="35" />
          <Setter Property="Padding" Value="5" />
          <Setter Property="Background" Value="#4E87D4" />
        </Style>
    
        <!-- List header text style -->
        <Style x:Key="listHeaderTextStyle" TargetType="{x:Type Label}">
          <Setter Property="Foreground" Value="White" />
          <Setter Property="VerticalAlignment" Value="Center" />
          <Setter Property="HorizontalAlignment" Value="Left" />
        </Style>
    
        <!-- Button style -->
        <Style x:Key="buttonStyle" TargetType="{x:Type Button}">
          <Setter Property="Width" Value="125" />
          <Setter Property="Height" Value="25" />
          <Setter Property="Margin" Value="0,10,0,0" />
          <Setter Property="HorizontalAlignment" Value="Right" />
        </Style>
    
      </Application.Resources>
    
    </Application>
    

    This XAML markup adds the following styles:

    • headerTextStyle: To format the page title Label.

    • labelStyle: To format the Label labels.

    • listHeaderStyle: To format the list header Border controls.

    • listHeaderTextStyle: To format the list header Label.

    • buttonStyle: To format the button on HomePage.xaml.

    Notice that the styles are resources are children of the Application.Resources property element. In this location, the styles are applied to all the elements in an application. For an example of using resources in a .NET Framework application, see How to: Use Application Resources.

  3. Open HomePage.xaml.

  4. Overwrite the content of the file with the following code. This step replaces with appearance-specific attributes of each element with an appropriate style.

    <Page 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.HomePage"
      WindowTitle="ExpenseIt"
      Title="ExpenseIt - Home" 
      WindowWidth="550" WindowHeight="380">
    
      <Grid>
        
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="230" />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition />
        </Grid.RowDefinitions>
    
        <DockPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0">
          <Canvas DockPanel.Dock="Left" Width="230" Height="100">
            <Image Style="{StaticResource backgroundImageStyle}" />
          </Canvas>
          <Label Style="{StaticResource headerTextStyle}">View Expense Report</Label>
        </DockPanel>
    
        <Grid Margin="10" Grid.Column="1" Grid.Row="1">
    
          <Grid.ColumnDefinitions>
            <ColumnDefinition />
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
            <RowDefinition Height="Auto" />
          </Grid.RowDefinitions>
          
          <!-- People list -->
          <Border Grid.Column="0" Grid.Row="0" Style="{StaticResource listHeaderStyle}">
            <Label Style="{StaticResource listHeaderTextStyle}">Names</Label>
          </Border>
          <ListBox Name="peopleListBox" Grid.Column="0" Grid.Row="1">
            <ListBoxItem>Mike</ListBoxItem>
            <ListBoxItem>Lisa</ListBoxItem>
            <ListBoxItem>John</ListBoxItem>
            <ListBoxItem>Mary</ListBoxItem>
          </ListBox>
    
          <!-- View report button -->
          <Button Grid.Column="0" Grid.Row="2" Style="{StaticResource buttonStyle}" 
            Click="viewButton_Click">View
          </Button>
    
        </Grid>
    
      </Grid>
    
    </Page>
    
  5. Open ExpenseReportPage.xaml.

  6. Overwrite the content of the file with the following code.

    <Page 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.ExpenseReportPage"
      Title="ExpenseIt - View Expense Report">
    
      <Grid>
    
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="230" />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition />
        </Grid.RowDefinitions>
    
        <DockPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0">
          <Canvas DockPanel.Dock="Left" Width="230" Height="100">
            <Image Style="{StaticResource backgroundImageStyle}" />
          </Canvas>
          <Label Style="{StaticResource headerTextStyle}">Expense Report For:</Label>
        </DockPanel>
    
        <Grid Margin="10" Grid.Column="1" Grid.Row="1">
    
          <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition />
          </Grid.RowDefinitions>
    
          <!-- Name -->
          <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Orientation="Horizontal">
            <Label Style="{StaticResource labelStyle}">Name:</Label>
            <Label Style="{StaticResource labelStyle}"></Label>
          </StackPanel>
    
          <!-- Department -->
          <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Orientation="Horizontal">
            <Label Style="{StaticResource labelStyle}">Department:</Label>
            <Label Style="{StaticResource labelStyle}"></Label>
          </StackPanel>
    
          <Grid Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3">
    
            <Grid.ColumnDefinitions>
              <ColumnDefinition />
              <ColumnDefinition Width="10" />
              <ColumnDefinition />
            </Grid.ColumnDefinitions>
    
            <Grid.RowDefinitions>
              <RowDefinition Height="Auto" />
              <RowDefinition />
            </Grid.RowDefinitions>
    
            <!-- Expense type list -->
            <Border Grid.Column="0" Grid.Row="0" Style="{StaticResource listHeaderStyle}">
              <Label Style="{StaticResource listHeaderTextStyle}">Expense Type</Label>
            </Border>
            <ListBox Grid.Column="0" Grid.Row="1" />
    
            <!-- Amount list -->
            <Border Grid.Column="2" Grid.Row="0" Style="{StaticResource listHeaderStyle}">
              <Label Style="{StaticResource listHeaderTextStyle}">Amount</Label>
            </Border>
            <ListBox Grid.Column="2" Grid.Row="1" />
    
          </Grid>
    
        </Grid>
    
      </Grid>
    
    </Page>
    
  7. Compile and run the application. After adding the XAML markup in this step, the application looks the same as it did before being updated with styles.

This step creates the XML data that is bound to various controls:

  1. Open HomePage.xaml.

  2. Overwrite the content of the file with the following XAML markup.

    <Page 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.HomePage"
      WindowTitle="ExpenseIt"
      Title="ExpenseIt - Home" 
      WindowWidth="550" WindowHeight="380">
    
      <Grid>
        
        <Grid.Resources>
    
          <!-- Expense Report Data -->
          <XmlDataProvider x:Key="ExpenseDataSource" XPath="Expenses">
            <x:XData>
              <Expenses xmlns="">
                <Person Name="Mike" Department="Legal">
                  <Expense ExpenseType="Lunch" ExpenseAmount="50" />
                  <Expense ExpenseType="Transportation" ExpenseAmount="50" />
                </Person>
                <Person Name="Lisa" Department="Marketing">
                  <Expense ExpenseType="Document printing"
                      ExpenseAmount="50"/>
                  <Expense ExpenseType="Gift" ExpenseAmount="125" />
                </Person>
                <Person Name="John" Department="Engineering">
                  <Expense ExpenseType="Magazine subscription" 
                     ExpenseAmount="50"/>
                  <Expense ExpenseType="New machine" ExpenseAmount="600" />
                  <Expense ExpenseType="Software" ExpenseAmount="500" />
                </Person>
                <Person Name="Mary" Department="Finance">
                  <Expense ExpenseType="Dinner" ExpenseAmount="100" />
                </Person>
              </Expenses>
            </x:XData>
          </XmlDataProvider>
    
          <!-- Name item template -->
          <DataTemplate x:Key="nameItemTemplate">
            <Label Content="{Binding XPath=@Name}"/>
          </DataTemplate>
    
        </Grid.Resources>
    
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="230" />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition />
        </Grid.RowDefinitions>
    
        <DockPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0">
          <Canvas DockPanel.Dock="Left" Width="230" Height="100">
            <Image Style="{StaticResource backgroundImageStyle}" />
          </Canvas>
          <Label Style="{StaticResource headerTextStyle}">View Expense Report</Label>
        </DockPanel>
    
        <Grid Margin="10" Grid.Column="1" Grid.Row="1">
    
          <Grid.ColumnDefinitions>
            <ColumnDefinition />
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
            <RowDefinition Height="Auto" />
          </Grid.RowDefinitions>
          
          <!-- People list -->
          <Border Grid.Column="0" Grid.Row="0" Style="{StaticResource listHeaderStyle}">
            <Label Style="{StaticResource listHeaderTextStyle}">Names</Label>
          </Border>
          <ListBox Name="peopleListBox" Grid.Column="0" Grid.Row="1" 
            ItemsSource="{Binding Source={StaticResource ExpenseDataSource}, XPath=Person}" 
            ItemTemplate="{StaticResource nameItemTemplate}" />
    
          <!-- View report button -->
          <Button Grid.Column="0" Grid.Row="2" Style="{StaticResource buttonStyle}" 
            Click="viewButton_Click">View</Button>
    
        </Grid>
    
      </Grid>
    
    </Page>
    

    Notice that the data is created as a Grid resource.

In this step, you write the code that retrieves the current item that is selected in the list of people on HomePage, 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 HomePage.xaml.cs.

  2. Overwrite the content of the file with the following code.

    C#
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    namespace ExpenseIt
    {
        public partial class HomePage : Page
        {
            public HomePage()
            {
                InitializeComponent();
            }
    
            private void viewButton_Click(object sender, RoutedEventArgs args)
            {
                // Create a new expense report page and pass it the selected person
                // by using the non-default constructor.
                ExpenseReportPage expenseReportPage = 
                    new ExpenseReportPage(this.peopleListBox.SelectedItem);
    
                // Navigate to the expense report page,
                this.NavigationService.Navigate(expenseReportPage);
            }
        }
    }
    
  3. Open ExpenseReportPage.xaml.cs.

  4. Overwrite the content of the file with the following code.

    C#
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    namespace ExpenseIt
    {
        public partial class ExpenseReportPage : Page
        {
            public ExpenseReportPage(object data)
            {
                InitializeComponent();
    
                // Bind to expense report data.
                this.DataContext = data;
            }
        }
    }
    

In this step, you update the UI for each item in the data bound lists by using data templates:

  1. Open ExpenseReportPage.xaml.

  2. Overwrite the content of the file with the following code.

    <Page 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="ExpenseIt.ExpenseReportPage"
      Title="ExpenseIt - View Expense Report">
    
      <Grid>
    
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="230" />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition />
        </Grid.RowDefinitions>
    
        <DockPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0">
          <Canvas DockPanel.Dock="Left" Width="230" Height="100">
            <Image Style="{StaticResource backgroundImageStyle}" />
          </Canvas>
          <Label Style="{StaticResource headerTextStyle}">Expense Report For:</Label>
        </DockPanel>
    
        <Grid Margin="10" Grid.Column="1" Grid.Row="1">
    
          <Grid.Resources>
            <!-- Reason item template -->
            <DataTemplate x:Key="typeItemTemplate">
              <Label Content="{Binding XPath=@ExpenseType}"/>
            </DataTemplate>
            <!-- Amount item template -->
            <DataTemplate x:Key="amountItemTemplate">
              <Label Content="{Binding XPath=@ExpenseAmount}"/>
            </DataTemplate>
          </Grid.Resources>
    
          <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition />
          </Grid.RowDefinitions>
    
          <!-- Name -->
          <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Orientation="Horizontal">
            <Label Style="{StaticResource labelStyle}">Name:</Label>
            <Label Content="{Binding XPath=@Name}" Style="{StaticResource labelStyle}"/>
          </StackPanel>
    
          <!-- Department -->
          <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Orientation="Horizontal">
            <Label Style="{StaticResource labelStyle}">Department:</Label>
            <Label Content="{Binding XPath=@Department}" Style="{StaticResource labelStyle}"/>
          </StackPanel>
          <Grid Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3">
    
            <Grid.ColumnDefinitions>
              <ColumnDefinition />
              <ColumnDefinition Width="10" />
              <ColumnDefinition />
            </Grid.ColumnDefinitions>
    
            <Grid.RowDefinitions>
              <RowDefinition Height="Auto" />
              <RowDefinition />
            </Grid.RowDefinitions>
    
            <!-- Expense type list -->
            <Border Grid.Column="0" Grid.Row="0" Style="{StaticResource listHeaderStyle}">
              <Label Style="{StaticResource listHeaderTextStyle}">Expense Type</Label>
            </Border>
            <ListBox Grid.Column="0" Grid.Row="1" ItemsSource="{Binding XPath=Expense}" 
              ItemTemplate="{StaticResource typeItemTemplate}" />
    
            <!-- Amount list -->
            <Border Grid.Column="2" Grid.Row="0" Style="{StaticResource listHeaderStyle}">
              <Label Style="{StaticResource listHeaderTextStyle}">Amount</Label>
            </Border>
            <ListBox Grid.Column="2" Grid.Row="1" ItemsSource="{Binding XPath=Expense}" 
              ItemTemplate="{StaticResource amountItemTemplate}" />
    
          </Grid>
    
        </Grid>
    
      </Grid>
    
    </Page>
    
  3. Compile and run the application.

Notice that the data templates are defined as Grid resources.

The following two figures show both pages of the ExpenseIt application with controls, layout, styles, data binding, and data templates applied:

ExpenseIt sample screen shots

This sample demonstrates a specific feature of the Windows Presentation Foundation and, consequently, does not follow application development best practices. For comprehensive coverage of Windows Presentation Foundation (WPF) and Microsoft .NET Framework application development best practices, refer to the following as appropriate:

Accessibility - Accessibility Best Practices

Security - Windows Presentation Foundation Security

Localization - WPF Globalization and Localization Overview

Optimizing WPF Application Performance

You now have a number of techniques at your disposal for creating a UI using Windows Presentation Foundation (WPF). You should now have a broad understanding of the basic building blocks of a data-bound .NET Framework 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.

Panels are explored in greater detail in the Panels Overview. Data templating is explored in greater depth in the Data Templating Overview.

Tags What's this?: c# (x) wpf (x) Add a tag
Community Content   What is Community Content?
Add new content RSS  Annotations
Nice Work      ProgCoop ... Thomas Lee   |   Edit   |   Show History
Great tutorial but VB would be better for many people.
Bad      PastLife_AReallyGoodDeveloper ... Thomas Lee   |   Edit   |   Show History

A bad tutorial. Got what I was supposed to.

Perhaps going into detail on what some of the code changes are doing as you go along might be nice. Really too much "overwrite and build" and not enough "doing this, and this is why".

I'll continue on to the "See Also" maybe I'll see more.

Is there a Visual Studio IDE version, as opposed to copy and paste code into files.

Just my two cents. Keep up the good work.

Flag as ContentBug
Good but need this      AbdulSami_US ... Richard645   |   Edit   |   Show History

Its good but I need VS 2008 IDE sample where I can use the same concept

Easy - as soon as you have created the .csproj file just open that with Visual Studio and continue using the IDE.


Tags What's this?: Add a tag
Flag as ContentBug
Good help      Uli1975   |   Edit   |   Show History
Right whats needed to get into WPF
Tags What's this?: Add a tag
Flag as ContentBug
WPF Tutorial      Christian Moser   |   Edit   |   Show History
Hi,

you can find another introduction to WPF here: http://www.wpftutorial.net
Was it too hard to add some VB code ??????      zino ... Thomas Lee   |   Edit   |   Show History
Was it too hard to add some VB code ??????
To those who ask for VB examples ... must we just give up?      Mike7491   |   Edit   |   Show History
To all those here who ask for more VB examples: I completely sympathize. I came to this environment thinking I would be able to leverage my many years of serious business system development using VBA. All those curly braces gave me the shivers. After months of struggle, it became clear that C# is now the language of first choice for most .NET commercial development. I finally decided I needed to just give up on VB, especially after determining that C# appears to impose more rigorous typing discipline than does VB. Somewhere, I recently read that the number of active C# developers has finally surpassed the number of active VB developers.

I'd love to hear some well-defended opinions: Should we just give up on VB?

Thanks.

-- M
Tags What's this?: .net (x) basic (x) c# (x) studio (x) vb (x) versus (x) visual (x) Add a tag
Flag as ContentBug
Processing
© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Page view tracker