共用方式為


逐步解說:WPF 使用者入門

更新:2010 年 12 月

本逐步解說介紹 Windows Presentation Foundation (WPF) 應用程式的開發,包括大多數 WPF 應用程式都會用到的項目:Extensible Application Markup Language (XAML) 標記、程式碼後置、應用程式定義、控制項、配置、資料繫結和樣式。

本逐步解說會透過下列步驟帶領您逐步開發出一個簡單的 WPF 應用程式。

  • 定義 XAML,以設計應用程式的user interface (UI) 外觀。

  • 撰寫程式碼,以建置應用程式的行為。

  • 建立應用程式定義,以管理應用程式。

  • 加入控制項和建立配置,以建立應用程式 UI。

  • 建立樣式,以建立一致的應用程式 UI 外觀。

  • 將 UI 繫結至資料以用資料填入 UI,並使資料和 UI 保持同步。

當您完成本逐步解說時,即建置好一支獨立的 Windows 應用程式,可以讓使用者檢視所選取人員的經費支出報表。 應用程式將由數個 WPF 頁面組成,這些頁面裝載在類似瀏覽器的視窗中。

用來建構此逐步解說的範例程式碼有 Microsoft Visual Basic 和 C# 兩種版本;請參閱建置 WPF 應用程式簡介 (英文)。

必要條件

您需要下列元件才能完成此逐步解說:

  • Visual Studio 2010

如需安裝 Visual Studio 的詳細資訊,請參閱 安裝 Visual Studio

建立應用程式專案

在本節中,您會建立應用程式基礎結構,包括一個應用程式定義、兩個頁面和一個影像。

  1. 在 Visual Basic 或 Visual C# 中,建立名為 ExpenseIt 的新 WPF 應用程式專案。 如需詳細資訊,請參閱 HOW TO:建立新的 WPF 應用程式專案

    注意事項注意事項

    這個逐步解說使用的 DataGrid 控制項只適用於 .NET Framework 4。請確定您的專案是以 .NET Framework 4 為目標。如需詳細資訊,請參閱 HOW TO:以特定的 .NET Framework 版本或設定檔為目標

  2. 開啟 Application.xaml (Visual Basic) 或 App.xaml (C#)。

    這個 XAML 檔案定義 WPF 應用程式和任何應用程式資源。您也可以使用這個檔案,指定會在應用程式啟動時自動顯示的 UI;在這個範例中,這個檔案是 MainWindow.xaml。

    您的 XAML 在 Visual Basic 中看起來應該如下所示:

    <Application x:Class="Application"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        StartupUri="MainWindow.xaml">
        <Application.Resources>
    
        </Application.Resources>
    </Application>
    

    或在 C# 中如下所示:

    <Application x:Class="ExpenseIt.App"
         xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
         StartupUri="MainWindow.xaml">
        <Application.Resources>
    
        </Application.Resources>
    </Application>
    
  3. 開啟 MainWindow.xaml。

    這個 XAML 檔案是應用程式的主視窗,可以分頁顯示建立的內容。 Window 類別會定義視窗的屬性 (例如其標題、大小或圖示),並且處理關閉或隱藏等事件。

  4. Window 項目變更為 NavigationWindow

    這個應用程式會隨使用者所做的互動,巡覽至不同的內容。 因此,主要 Window 需要變更為 NavigationWindowNavigationWindow 會繼承 Window 的所有屬性。 XAML 檔中的 NavigationWindow 項目會建立 NavigationWindow 類別的執行個體。 如需詳細資訊,請參閱巡覽概觀

  5. 變更 NavigationWindow 項目上的下列屬性:

    您的 XAML 在 Visual Basic 中看起來應該如下所示:

    <NavigationWindow x:Class="MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500">
    
    </NavigationWindow>
    

    或在 C# 中如下所示:

    <NavigationWindow x:Class="ExpenseIt.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500">
    
    </NavigationWindow>
    
  6. 開啟 MainWindow.xaml.vb 或 MainWindow.xaml.cs。

    這個檔案是程式碼後置的檔案,其包含的程式碼要處理在 MainWindow.xaml 中宣告的事件。 這個檔案包含 XAML 中定義之視窗的部分類別。

  7. 如果您使用的是 C#,請將 MainWindow 類別變更為衍生自 NavigationWindow

    在 Visual Basic 中,當您在 XAML 中變更此視窗時,會自動執行這個動作。

    您的程式碼應該像這樣。

    Class MainWindow
    
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace ExpenseIt
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : NavigationWindow
        {
            public MainWindow()
            {
                InitializeComponent();
            }
        }
    }
    

將檔案加入至應用程式

在本節中,您會將兩個頁面和一個影像加入至應用程式。

  1. 將新頁面 (WPF) 加入至名為 ExpenseItHome.xaml 的專案。 如需詳細資訊,請參閱 HOW TO:加入新項目至 WPF 專案

    這個頁面會是應用程式啟動時顯示的第一頁。 它會顯示一份人員清單,使用者可從中選取一名人員查看其經費支出報表。

  2. 開啟 ExpenseItHome.xaml。

  3. Title 設定為 "ExpenseIt - Home"。

    您的 XAML 在 Visual Basic 中看起來應該如下所示:

    <Page x:Class="ExpenseItHome"
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="https://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"
      Title="ExpenseIt - Home">
        <Grid>
    
        </Grid>
    </Page>
    

    或在 C# 中如下所示:

    <Page x:Class="ExpenseIt.ExpenseItHome"
          xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="https://schemas.microsoft.com/expression/blend/2008" 
          mc:Ignorable="d" 
          d:DesignHeight="300" d:DesignWidth="300"
        Title="ExpenseIt - Home">
    
        <Grid>
    
        </Grid>
    </Page>
    
  4. 開啟 MainWindow.xaml。

  5. NavigationWindow 上的 Source 屬性設定為 "ExpenseItHome.xaml"。

    這會將 ExpenseItHome.xaml 設定為應用程式啟動時開啟的第一頁。 您的 XAML 在 Visual Basic 中看起來應該如下所示:

    <NavigationWindow x:Class="MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500" Source="ExpenseItHome.xaml">
    
    </NavigationWindow>
    

    或在 C# 中如下所示:

    <NavigationWindow x:Class="ExpenseIt.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500" Source="ExpenseItHome.xaml">
    
    </NavigationWindow>
    
  6. 將新分頁 (WPF) 加入至名為 ExpenseReportPage.xaml 的專案。

    這個頁面將顯示從 ExpenseItHome.xaml 中選取之人員的經費支出報表。

  7. 開啟 ExpenseReportPage.xaml。

  8. Title 設定為 "ExpenseIt - View Expense"。

    您的 XAML 在 Visual Basic 中看起來應該如下所示:

    <Page x:Class="ExpenseReportPage"
          xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="https://schemas.microsoft.com/expression/blend/2008" 
          mc:Ignorable="d" 
          d:DesignHeight="300" d:DesignWidth="300"
          Title="ExpenseIt - View Expense">
        <Grid>
    
        </Grid>
    </Page>
    

    或在 C# 中如下所示:

    <Page x:Class="ExpenseIt.ExpenseReportPage"
          xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="https://schemas.microsoft.com/expression/blend/2008" 
          mc:Ignorable="d" 
          d:DesignHeight="300" d:DesignWidth="300"
        Title="ExpenseIt - View Expense">
    
        <Grid>
    
        </Grid>
    </Page>
    
  9. 開啟 ExpenseItHome.xaml.vb 和 ExpenseReportPage.xaml.vb,或開啟 ExpenseItHome.xaml.cs 和 ExpenseReportPage.xaml.cs。

    當您建立新的分頁檔時,Visual Studio 會自動建立程式碼後置檔案。 這些程式碼後置檔案會處理用於回應使用者輸入的邏輯。

    您的程式碼應該像這樣。

    Class ExpenseItHome
    
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace ExpenseIt
    {
        /// <summary>
        /// Interaction logic for ExpenseItHome.xaml
        /// </summary>
        public partial class ExpenseItHome : Page
        {
            public ExpenseItHome()
            {
                InitializeComponent();
            }
        }
    }
    
    Class ExpenseReportPage
    
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace ExpenseIt
    {
        /// <summary>
        /// Interaction logic for ExpenseReportPage.xaml
        /// </summary>
        public partial class ExpenseReportPage : Page
        {
            public ExpenseReportPage()
            {
                InitializeComponent();
            }
        }
    }
    
  10. 將名為 watermark.png 的影像加入至專案。 您可以建立自己的影像,或是複製範例程式碼中的檔案。 如需詳細資訊,請參閱 HOW TO:加入現有項目至專案

建置和執行應用程式

此本節中,您會建置和執行應用程式。

  1. 按 F5 或是選取 [偵錯] 功能表中的 [開始偵錯],以建置和執行應用程式。

    下圖顯示具有 NavigationWindow 按鈕的應用程式。

    ExpenseIt 範例螢幕擷取畫面

  2. 關閉應用程式以回到 Visual Studio。

建立配置

配置提供一種有次序的放置 UI 項目的方式,並且管理調整 UI 大小時這些項目的大小和位置。 您通常會建立具有下列其中一個控制項的配置:

以上這些配置控制項都支援一種用於其子項目的特殊配置類型。 ExpenseIt 頁面的大小可以調整,各頁面都有項目會沿著其他項目水平和垂直排列。 因此,Grid 是應用程式理想的配置項目。

注意事項注意事項

如需 Panel 項目的詳細資訊,請參閱面板概觀。如需配置的詳細資訊,請參閱配置系統

在本節中,您會將欄和列定義加入至 ExpenseItHome.xaml 中的 Grid,以建立含有一欄三列、邊界為 10 個像素的表格。

  1. 開啟 ExpenseItHome.xaml。

  2. Grid 項目上的 Margin 屬性設定為 "10,0,10,10",以對應上、下、左、右邊界。

  3. 將下列 XAML 加入至 Grid 標籤之間,以建立列和欄定義。 

    <Grid.ColumnDefinitions>
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    

    有兩列的 Height 會設定為 Auto,這表示這些列會根據列中的內容調整大小。 預設 HeightStar 大小,這表示列的大小會是其在可用空間的加權比例。 例如,如果有兩列的高度都是 "*",則每列的高度會各佔可用空間的一半。

    您的 Grid 現在應該如下列 XAML 所示:

    <Grid Margin="10,0,10,10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition />
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
    </Grid>
    

加入控制項

在本節中,會將首頁 UI 更新成顯示人員清單,讓使用者可從中選取人員以顯示所選取人員的經費支出報表。 控制項是使用者藉以與您的應用程式互動的 UI 物件。 如需詳細資訊,請參閱控制項

為了建立這個 UI,下列項目會加入至 ExpenseItHome.xaml:

  • ListBox (用於人員的清單)。

  • Label (用於清單標題)。

  • Button (按一下即可檢視從清單中選取的人員的經費支出報表)。

每個控制項都是藉由設定 Grid.Row 附加屬性的方式,放置在 Grid 的列中。 如需附加屬性的詳細資訊,請參閱附加屬性概觀

  1. 開啟 ExpenseItHome.xaml。

  2. Grid 標籤之間加入下列 XAML。

    
      <!-- 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>
    
  3. 建置並執行應用程式。

下圖顯示本節中的 XAML 所建立的控制項。

ExpenseIt 範例螢幕擷取畫面

加入影像和標題

在本節中,會使用影像和頁面標題更新首頁 UI。

  1. 開啟 ExpenseItHome.xaml。

  2. 將具有 230 像素固定 Width 的另一欄,加入至 ColumnDefinitions

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    
  3. 將另一列加入至 RowDefinitions

    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    
  4. Grid.Column 設定為 1,以將控制項移至第二欄。 將 Grid.Row 加 1,以將每個控制項下移一列。

      <Border Grid.Column="1" Grid.Row="1" Height="35" Padding="5" Background="#4E87D4">
          <Label VerticalAlignment="Center" Foreground="White">Names</Label>
      </Border>
      <ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2">
          <ListBoxItem>Mike</ListBoxItem>
          <ListBoxItem>Lisa</ListBoxItem>
          <ListBoxItem>John</ListBoxItem>
          <ListBoxItem>Mary</ListBoxItem>
      </ListBox>
    
      <!-- View report button -->
      <Button Grid.Column="1" Grid.Row="3" Margin="0,10,0,0" Width="125"
    Height="25" HorizontalAlignment="Right">View</Button>
    
  5. GridBackground 設定為 watermark.png 影像檔。

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png"/>
    </Grid.Background>
    
  6. Border 之前,加入內容為 "View Expense Report" 的 Label 做為頁面的標題。

    <Label Grid.Column="1" VerticalAlignment="Center" FontFamily="Trebuchet MS" 
            FontWeight="Bold" FontSize="18" Foreground="#0066cc">
        View Expense Report
    </Label>
    
  7. 建置並執行應用程式。

下圖顯示本節的結果。

ExpenseIt 範例螢幕擷取畫面

加入程式碼以處理事件

  1. 開啟 ExpenseItHome.xaml。

  2. Click 事件處理常式加入至 Button 項目。 如需詳細資訊,請參閱 HOW TO:建立簡單的事件處理常式

      <!-- View report button -->
      <Button Grid.Column="1" Grid.Row="3" Margin="0,10,0,0" Width="125"
    Height="25" HorizontalAlignment="Right" Click="Button_Click">View</Button>
    
  3. 開啟 ExpenseItHome.xaml.vb 或 ExpenseItHome.xaml.cs。

  4. 將下列程式碼加入至 Click 事件處理常式,這個程式碼會使視窗巡覽至 ExpenseReportPage.xaml 檔案。

            Private Sub Button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
                ' View Expense Report
                Dim expenseReportPage As New ExpenseReportPage()
                Me.NavigationService.Navigate(expenseReportPage)
    
            End Sub
    
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // View Expense Report
        ExpenseReportPage expenseReportPage = new ExpenseReportPage();
        this.NavigationService.Navigate(expenseReportPage);
    
    }
    

建立 ExpenseReportPage 的 UI

ExpenseReportPage.xaml 將顯示從 ExpenseItHome.xaml 中選取之人員的經費支出報表。 本節會加入控制項並建立 ExpenseReportPage.xaml 的 UI。 同時也會將背景和填滿色彩加入至各個 UI 項目。

  1. 開啟 ExpenseReportPage.xaml。

  2. Grid 標籤之間加入下列 XAML。

    這個 UI 與 ExpenseItHome.xaml 上建立的 UI 類似,只不過報告資料是顯示在 DataGrid 中。

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png" />
    </Grid.Background>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>
    
    
    <Label Grid.Column="1" VerticalAlignment="Center" FontFamily="Trebuchet MS" 
    FontWeight="Bold" FontSize="18" Foreground="#0066cc">
        Expense Report For:
    </Label>
    <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="2" VerticalAlignment="Top" 
              HorizontalAlignment="Left">
            <!-- Expense type and Amount table -->
            <DataGrid  AutoGenerateColumns="False" RowHeaderWidth="0" >
                <DataGrid.ColumnHeaderStyle>
                    <Style TargetType="{x:Type DataGridColumnHeader}">
                        <Setter Property="Height" Value="35" />
                        <Setter Property="Padding" Value="5" />
                        <Setter Property="Background" Value="#4E87D4" />
                        <Setter Property="Foreground" Value="White" />
                    </Style>
                </DataGrid.ColumnHeaderStyle>
                <DataGrid.Columns>
                    <DataGridTextColumn Header="ExpenseType" />
                    <DataGridTextColumn Header="Amount"  />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Grid>
    
  3. 建置並執行應用程式。

    注意事項注意事項

    如果您收到 DataGrid 找不到或不存在的錯誤,請確認您的專案目標是 .NET Framework 4。如需詳細資訊,請參閱 HOW TO:以特定的 .NET Framework 版本或設定檔為目標

  4. 按一下 [檢視] 按鈕。

    支出報告頁面隨即出現。

下圖顯示加入至 ExpenseReportPage.xaml 的 UI 項目。 請注意,上一頁巡覽按鈕已啟用。

ExpenseIt 範例螢幕擷取畫面

樣式控制項

在 UI 中有各種項目,其中所有同類型的項目外觀通常一樣。 UI 利用樣式使多個項目可重複使用同一外觀。 重複使用樣式可以簡化 XAML 的建立和管理。 如需樣式的詳細資訊,請參閱設定樣式和範本。 本節會將先前步驟中定義的個別項目屬性 (Attribute) 取代為樣式。

  1. 開啟 Application.xaml 或 App.xaml。

  2. Application.Resources 標籤之間加入下列 XAML:

    
    <!-- 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>
    
    <!-- DataGrid header style -->
    <Style x:Key="columnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
        <Setter Property="Height" Value="35" />
        <Setter Property="Padding" Value="5" />
        <Setter Property="Background" Value="#4E87D4" />
        <Setter Property="Foreground" Value="White" />
    </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>
    

    這個 XAML 會加入下列樣式:

    • headerTextStyle:設定頁面標題 Label 的格式。

    • labelStyle:設定 Label 控制項的格式。

    • columnHeaderStyle:格式化 DataGridColumnHeader

    • listHeaderStyle:設定清單標題 Border 控制項的格式。

    • listHeaderTextStyle:設定清單標題 Label 的格式。

    • buttonStyle:設定 ExpenseItHome.xaml 上 Button 的格式。

    請注意,樣式是 Application.Resources 屬性 (Property) 項目的資源和子系。 在這裡,樣式會套用至應用程式中的所有項目。 如需在 .NET Framework 應用程式中使用資源的範例,請參閱HOW TO:使用應用程式資源

  3. 開啟 ExpenseItHome.xaml。

  4. 以下列 XAML 取代 Grid 項目之間的一切內容。

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png"  />
    </Grid.Background>
    
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    
    <!-- People list -->
    
    <Label Grid.Column="1" Style="{StaticResource headerTextStyle}" >
        View Expense Report
    </Label>
    
    <Border Grid.Column="1" Grid.Row="1" Style="{StaticResource listHeaderStyle}">
        <Label Style="{StaticResource listHeaderTextStyle}">Names</Label>
    </Border>
    <ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2">
        <ListBoxItem>Mike</ListBoxItem>
        <ListBoxItem>Lisa</ListBoxItem>
        <ListBoxItem>John</ListBoxItem>
        <ListBoxItem>Mary</ListBoxItem>
    </ListBox>
    
    <!-- View report button -->
    <Button Grid.Column="1" Grid.Row="3" Click="Button_Click" Style="{StaticResource buttonStyle}">View</Button>
    

    VerticalAlignmentFontFamily 等用於定義每個控制項之外觀的屬性,會因套用樣式而遭移除和取代。 例如,headerTextStyle 就會套用至 "View Expense Report" 這個 Label

  5. 開啟 ExpenseReportPage.xaml。

  6. 以下列 XAML 取代 Grid 項目之間的一切內容。

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png" />
    </Grid.Background>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>
    
    
    <Label Grid.Column="1" Style="{StaticResource headerTextStyle}">
        Expense Report For:
    </Label>
    <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="2" VerticalAlignment="Top" 
              HorizontalAlignment="Left">
            <!-- Expense type and Amount table -->
            <DataGrid ColumnHeaderStyle="{StaticResource columnHeaderStyle}" 
                      AutoGenerateColumns="False" RowHeaderWidth="0" >
                <DataGrid.Columns>
                    <DataGridTextColumn Header="ExpenseType" />
                    <DataGridTextColumn Header="Amount"  />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Grid>
    

    這麼做會將樣式加入至 LabelBorder 項目。

  7. 建置並執行應用程式。

    加入本節中的 XAML 標記後,應用程式看起來和更新成樣式之前一樣。

將資料繫結至控制項

在本節中,您會建立繫結至各個控制項的 XML 資料。

  1. 開啟 ExpenseItHome.xaml。

  2. 在開頭 Grid 項目後面,加入下列 XAML 以建立含有各人資料的 XmlDataProvider

    此資料是建立成 Grid 資源。 此資料通常會以檔案形式載入,但是為求簡單,此資料會以內嵌方式加入。

    <Grid.Resources>
    
    
    ...
    
    
    <!-- Expense Report Data -->
    <XmlDataProvider x:Key="ExpenseDataSource" XPath="Expenses">
        <x:XData>
            <Expenses >
                <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>
    
    
    ...
    
    
    </Grid.Resources>
    
  3. Grid 資源中,加入下列 DataTemplate,以定義在 ListBox 中顯示資料的方式。 如需資料範本的詳細資訊,請參閱資料範本化概觀

    <Grid.Resources>
    
    
    ...
    
    
    <!-- Name item template -->
    <DataTemplate x:Key="nameItemTemplate">
        <Label Content="{Binding XPath=@Name}"/>
    </DataTemplate>
    
    
    ...
    
    
    </Grid.Resources>
    
  4. 以下列 XAML 取代現有的 ListBox

    <ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2" 
             ItemsSource="{Binding Source={StaticResource ExpenseDataSource}, XPath=Person}"
             ItemTemplate="{StaticResource nameItemTemplate}">
    </ListBox>
    

    此 XAML 會將 ListBoxItemsSource 屬性繫結至資料來源,並套用資料範本做為 ItemTemplate

將資料連接到控制項

在本節中,您會撰寫程式碼來擷取目前在 ExpenseItHome.xaml 頁面的人員清單中選取的項目,並且在執行個體化期間將該項目的參考傳遞至 ExpenseReportPage 的建構函式。 ExpenseReportPage 會以傳遞的項目設定自己的資料內容,而這也就是 ExpenseReportPage.xaml 中定義的控制項將繫結的項目。

  1. 開啟 ExpenseReportPage.xaml.vb 或 ExpenseReportPage.xaml.cs。

  2. 加入接受一個物件的建構函式,以便您可以傳遞所選人員的經費支出報表資料。

        Partial Public Class ExpenseReportPage
            Inherits Page
            Public Sub New()
                InitializeComponent()
            End Sub
    
            ' Custom constructor to pass expense report data
            Public Sub New(ByVal data As Object)
                Me.New()
                ' Bind to expense report data.
                Me.DataContext = data
            End Sub
    
        End Class
    
    public partial class ExpenseReportPage : Page
    {
        public ExpenseReportPage()
        {
            InitializeComponent();
        }
    
        // Custom constructor to pass expense report data
        public ExpenseReportPage(object data):this()
        {
            // Bind to expense report data.
            this.DataContext = data;
        }
    
    }
    
  3. 開啟 ExpenseItHome.xaml.vb 或 ExpenseItHome.xaml.cs。

  4. 變更 Click 事件處理常式,以呼叫這個會傳遞所選人員之經費支出報表資料的新建構函式。

            Private Sub Button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
                ' View Expense Report
                Dim expenseReportPage As New ExpenseReportPage(Me.peopleListBox.SelectedItem)
                Me.NavigationService.Navigate(expenseReportPage)
    
            End Sub
    
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // View Expense Report
        ExpenseReportPage expenseReportPage = new ExpenseReportPage(this.peopleListBox.SelectedItem);
        this.NavigationService.Navigate(expenseReportPage);
    
    }
    

使用資料範本設定資料的樣式

在本節中,您會使用資料範本來更新資料繫結清單中每個項目的 UI:

  1. 開啟 ExpenseReportPage.xaml。

  2. 將 "Name" 和 "Department" 這兩個 Label 項目的內容繫結至適當的資料來源屬性 (Property)。 如需資料繫結的詳細資訊,請參閱資料繫結概觀

    <!-- Name -->
    <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Orientation="Horizontal">
        <Label Style="{StaticResource labelStyle}">Name:</Label>
        <Label Style="{StaticResource labelStyle}" Content="{Binding XPath=@Name}"></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}" Content="{Binding XPath=@Department}"></Label>
    </StackPanel>
    
  3. Grid 起始項目之後,加入下列資料範本,以定義顯示經費支出報表資料的方式。

    <!--Templates to display expense report data-->
    <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>
    
  4. 將範本套用至會顯示經費支出報表資料的 DataGrid 資料行。

    <!-- Expense type and Amount table -->
    <DataGrid ItemsSource="{Binding XPath=Expense}" ColumnHeaderStyle="{StaticResource columnHeaderStyle}" AutoGenerateColumns="False" RowHeaderWidth="0" >
    
        <DataGrid.Columns>
            <DataGridTextColumn Header="ExpenseType" Binding="{Binding XPath=@ExpenseType}"  />
            <DataGridTextColumn Header="Amount" Binding="{Binding XPath=@ExpenseAmount}" />
        </DataGrid.Columns>
    
    </DataGrid>
    
  5. 建置並執行應用程式。

  6. 選取人員並按一下 [檢視] 按鈕。

下圖顯示 ExpenseIt 應用程式套用控制項、配置、樣式、資料繫結和資料範本後的兩個頁面。

ExpenseIt 範例螢幕擷取畫面

最佳作法

這個範例示範 WPF 的特定功能,因此並未遵循應用程式開發的最佳作法。 如需 WPF 和 .NET Framework 應用程式開發最佳做法的完整內容,請依適當情況參閱下列主題:

下一步

現在您已經具備了用 Windows Presentation Foundation (WPF) 建立 UI 的幾個技巧,您可以隨意運用。 您也應該對資料繫結 .NET Framework 應用程式的基本建置組塊有了更深的了解。 很明顯的,這個主題並未詳盡說明一切方法,但是希望您在學得本主題的技巧後,能夠獲得一些概念,以探索更多可能性。

如需 WPF 架構和程式撰寫模型的詳細資訊,請參閱下列主題:

如需建立應用程式的詳細資訊,請參閱下列主題:

請參閱

概念

面板概觀

資料範本化概觀

建置 WPF 應用程式 (WPF)

其他資源

樣式和範本

變更記錄

日期

記錄

原因

2010 年 12 月

新增注意事項來說明要以 .NET Framework 4 為目標。

資訊加強。