共用方式為


教學課程:在 Visual Studio 2019 中建立您的第一個 WPF 應用程式

本文說明如何開發 Windows Presentation Foundation (WPF) 傳統型應用程式,其中包含大多數 WPF 應用程式常見元素:Extensible Application Markup Language (XAML) 標記、程式碼後置、應用程式定義、控制項、版面配置、資料繫結和樣式。 若要開發應用程式,您將使用 Visual Studio。

重要

本文針對 .NET Framework 所撰寫。 若要開始使用 .NET 7,請參閱教學課程:建立新的 WPF 應用程式 (WPF .NET)

在本教學課程中,您會了解如何:

  • 建立 WPF 專案。
  • 使用 XAML 以設計應用程式的使用者介面 (UI) 外觀。
  • 撰寫程式碼以建置應用程式的行為。
  • 建立應用程式定義以管理應用程式。
  • 加入控制項和建立版面配置,以組成應用程式。
  • 為整個應用程式維持一致外觀建立樣式。
  • 將 UI 繫結至資料,同時從資料填入 UI,以及讓資料和 UI 保持同步。

在教學課程結束後,您就會建置一個獨立的 Windows 應用程式,可讓使用者檢視所選取人員的費用報表。 應用程式由數個 WPF 頁面組成,這些頁面裝載於瀏覽器樣式的視窗中。

提示

本教學課程中使用的範例程式碼適用於教學課程 WPF 應用程式範例程式碼的 Visual Basic 和 C#,。

您可以使用此頁面頂端的語言選取器,在 C# 和 Visual Basic 之間切換範例程式碼的程式碼語言。

必要條件

建立應用程式專案

第一步是建立應用程式基礎結構,包括一個應用程式定義、兩個頁面和一個影像。

  1. 在 Visual Basic 或 Visual C# 中,建立名為 ExpenseIt 的新 WPF 應用程式專案:

    1. 開啟 Visual Studio,並在 [開始] 功能表下方選取 [建立新專案]

      會開啟 [建立新專案] 對話方塊。

    2. 在 [語言] 下拉式清單中,選擇 [C#] 或 [Visual Basic]

    3. 選取 [WPF 應用程式 (.NET Framework)] 範本,然後選取 [下一步]

      [建立新專案] 對話方塊

      會開啟 [設定新專案] 對話方塊。

    4. 輸入專案名稱 ExpenseIt,然後選取 [建立]

      [設定新專案] 對話方塊

      Visual Studio 建立專案,並為名為 MainWindow.xaml 之預設應用程式視窗開啟設計工具。

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

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

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

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

    並在 C# 中如下所示:

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

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

  4. Window 元素變更為 NavigationWindow,如下列 XAML 中所示:

    <NavigationWindow x:Class="ExpenseIt.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         ...
    </NavigationWindow>
    

    這個應用程式會根據使用者的輸入瀏覽至不同的內容。 這就是為什麼主要 Window 需要變更為 NavigationWindowNavigationWindow 會繼承 Window 的所有屬性。 XAML 檔案中的 NavigationWindow 元素會建立 NavigationWindow 類別的執行個體。 如需詳細資訊,請參閱瀏覽概觀

  5. NavigationWindow 標籤之間移除 Grid 元素。

  6. 變更 NavigationWindow 元素的 XAML 程式碼中下列屬性:

    • Title 屬性設定為 「ExpenseIt」。

    • Height 屬性設定為 350 像素。

    • Width 屬性設定為 500 像素。

    您的 XAML 看起來應該與下列 Visual Basic 範例相同:

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

    並且與下列 C# 範例相同:

    <NavigationWindow x:Class="ExpenseIt.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500">
        
    </NavigationWindow>
    
  7. 開啟 MainWindow.xaml.vbMainWindow.xaml.cs

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

  8. 如果您正在使用 C#,將類別 MainWindow 變更為 NavigationWindow 的衍生。 (在 Visual Basic 中,當您在 XAML 中變更視窗時會自動發生。)您的 C# 程式碼外觀現在應該如下圖所示:

    
    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. 將新頁面新增至專案,並將其命名為 ExpenseItHome.xaml

    1. 在 [方案總管] 中,以滑鼠右鍵按一下 ExpenseIt 專案節點,然後選擇 [新增] > [新資料夾]

    2. 在 [新增專案] 對話方塊中,頁面 (WPF) 範本已選取。 輸入名稱 ExpenseItHome,然後選取 [新增]

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

  2. 開啟 [ExpenseItHome.xaml]。

  3. Title 設定為「ExpenseIt - Home」。

  4. DesignHeight 設為 350 像素,並將 DesignWidth 設為 500 像素。

    現在會顯示 XAML,如下方 Visual Basic 所示:

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

    並且與下列 C# 範例相同:

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

  6. Source 屬性新增至 NavigationWindow 元素,並將其設定為「ExpenseItHome.xaml」。

    這會將 ExpenseItHome.xaml 設成應用程式啟動時開啟的第一個頁面。

    Visual Basic 中的 XAML 範例:

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

    以及在 C# 中:

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

    提示

    您也可以設定 [屬性] 視窗 [其他] 類別中的資源屬性。

    [屬性] 視窗中的資源屬性

  7. 將另一個新的 WPF 頁面新增至專案,並將其命名為 ExpenseReportPage.xaml:

    1. 在 [方案總管] 中,以滑鼠右鍵按一下 ExpenseIt 專案節點,然後選擇 [新增] > [新資料夾]

    2. 在 [新增元素] 對話方塊中,選取 [頁面 (WPF)]。 輸入 ExpenseReportPage 名稱,然後選取 [新增]

    這個頁面會顯示 ExpenseItHome 頁面中所選取之人員的費用報表。

  8. 開啟 ExpenseReportPage.xaml

  9. Title 設定為「ExpenseIt - View Expense」。

  10. DesignHeight 設為 350 像素,並將 DesignWidth 設為 500 像素。

    ExpenseReportPage.xaml 現在在 Visual Basic 中如下所示:

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

    並在 C# 中如下所示:

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

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

    您的程式碼應該看起來與下列 ExpenseItHome 範例相同:

    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 ExpenseItHome
    
    End Class
    

    與下列 ExpenseReportPage 範例相同:

    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();
            }
        }
    }
    
    Class ExpenseReportPage
    
    End Class
    
  12. 將名為 watermark.png 的影像加入至專案。 您可以建立自己的影像、從範例程式碼複製檔案,或從 microsoft/WPF-Samples GitHub 存放庫取得檔案。

    1. 以滑鼠右鍵按一下專案節點,然後選取 [新增] > [現有元素],然後按一下 [Shift+Alt+A]

    2. 在 [新增現有元素] 對話方塊中,將檔案篩選設定為 [所有檔案] 或 [影像檔案],瀏覽至要使用的影像檔案,然後選取 [新增]

    3. 在 [方案總管] 中選取影像檔案,然後在 [屬性] 視窗中,將 [建置動作] 設定為 [資源]

建置並執行應用程式

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

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

    建置並執行後的應用程式。

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

建立配置

版面配置會按照順序放置 UI 元素,也會在重新調整 UI 大小時管理這些元素的大小和位置。 您通常會建立具有下列其中一個版面配置控制項的版面配置:

  • Canvas - 使用區域的相對座標,定義可以明確定位子元素位置的 Canvas 區域。
  • DockPanel - 定義可以水平或垂直 (相對於其他子元素) 排列子元素的區域。
  • Grid - 定義彈性的格線區域,由欄與列組成。
  • StackPanel - 將子元素排成單一行,以水平或垂直方式排列。
  • VirtualizingStackPanel - 排列和虛擬化單一水平或垂直行的內容。
  • WrapPanel - 將子元素置放於由左至右的連續位置,其中會在包含方塊的邊緣將內容換至下一行。 後續順序會依序由上而下或由左而右,需視方向屬性的值而定。

這些版面配置控制項都支援其子元素的特殊版面配置類型。 ExpenseIt 頁面可以調整大小,而且每個頁面都有元素會沿著其他元素水平和垂直排列。 在此範例中,Grid 用於應用程式的版面配置元素。

提示

如需 Panel 元素的詳細資訊,請參閱面板概觀。 如需版面配置的詳細資訊,請參閱 版面配置

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

  1. ExpenseItHome.xaml 中,將 Grid 元素上的 Margin 屬性設定為 「10,0,10,10」,其對應至左邊、上方、右邊和下方邊界:

    <Grid Margin="10,0,10,10">
    

    提示

    您也可以在 [屬性] 視窗中的 [版面配置] 類別下方設定 [邊界] 值:

    屬性視窗中的 [邊界] 值

  2. Grid 標籤中加入下列 XAML 程式碼,以建立資料列和資料行定義:

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

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

    您的 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.xamlGrid 標籤之間加入下列 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,10" Width="125" Height="25" HorizontalAlignment="Right">View</Button>
    

    提示

    您也可以將控制項從 [工具箱] 視窗拖放至 [設計] 視窗,然後在 [屬性] 視窗中設定其屬性,以這種方式建立控制項。

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

    下圖顯示影像您建立的控制項:

ExpenseIt 範例螢幕擷取畫面,其中顯示名稱清單

新增影像和標題

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

  1. ExpenseItHome.xaml 中,將另一個資料行新增至具有固定 Width 230 像素的 ColumnDefinitions

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    
  2. 將另一個資料列新增至 RowDefinitions,總共會有四個資料列:

    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    
  3. 將三個控制項中的 Grid.Column 屬性設定為 1,將控制項移動至第二個資料行 (Border、ListBox 和 Button)。

  4. 將每一個控制項的 Grid.Row 值遞增為 1,以將每個控制項遞減一個資料列 (Border、ListBox 和 Button) 以及 Border 元素。

    三個控制項的 XAML 現在如下列所示:

      <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. Background 屬性設定為 watermark.png 影像檔,方法是在 <Grid></Grid> 標籤之間新增下列 XAML:

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png"/>
    </Grid.Background>
    
  6. Border 元素之前,新增具有「檢視費用報表」內容的 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 中,新增 Click 事件處理常式至 Button 元素。 如需詳細資訊,請參閱操作說明:建立簡單的事件處理常式

      <!-- 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>
    
  2. 開啟 ExpenseItHome.xaml.vbExpenseItHome.xaml.cs

  3. 將下列點擊按鈕事件處理常式程式碼新增至 ExpenseItHome 類別。 事件處理常式會開啟 ExpenseReportPage 頁面。

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // View Expense Report
        ExpenseReportPage expenseReportPage = new ExpenseReportPage();
        this.NavigationService.Navigate(expenseReportPage);
    }
    
    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
    

建立 ExpenseReportPage 的 UI

ExpenseReportPage.xaml 會顯示在 ExpenseItHome 頁面上選取之人員的費用報表。 在本節中,您將建立 ExpenseReportPage 的 UI。 您會將背景和填滿色彩加入至各個 UI 元素。

  1. 開啟 ExpenseReportPage.xaml

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

     <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>
    

    此UI與 ExpenseItHome.xaml 類似,但報表資料會顯示在 DataGrid

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

  4. 選取 [檢視] 按鈕。

    報表頁面隨即出現。 請注意,返回導覽按鈕已啟用。

下圖顯示加入至 ExpenseReportPage.xaml 的 UI 元素。

ExpenseIt 範例螢幕擷取畫面,其中顯示剛為 ExpenseReportPage 建立的 UI。

樣式控制項

在 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 屬性元素的資源和子系。 在這裡,樣式會套用至應用程式中的所有元素。 如需在 .NET 應用程式中使用資源的範例,請參閱使用應用程式資源

  3. 開啟 ExpenseItHome.xaml,並以下列 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 會套用至「檢視費用報表」Label

  4. 開啟 ExpenseReportPage.xaml

  5. 使用下列 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>
    

    這樣會將 XAML 加入 LabelBorder 元素。

  6. 建置並執行應用程式。 視窗外觀與先前相同。

    ExpenseIt 範例螢幕擷取畫面,其外觀與上一節相同。

  7. 關閉應用程式以返回 Visual Studio。

將資料繫結到控制項

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

  1. ExpenseItHome.xaml 中,開啟 Grid 元素之後,新增下列 XAML 來建立包含每個人員資料的 XmlDataProvider

    <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>
    </Grid.Resources>
    

    資料會建立為 Grid 資源。 此資料通常會載入為檔案,但為求簡化會內嵌資料。

  2. <Grid.Resources> 元素內,新增下列 <xref:System.Windows.DataTemplate> 元素,其定義如何在 <XmlDataProvider> 元素之後,於 ListBox 中顯示資料:

    <Grid.Resources>
        <!-- Name item template -->
        <DataTemplate x:Key="nameItemTemplate">
            <Label Content="{Binding XPath=@Name}"/>
        </DataTemplate>
    </Grid.Resources>
    

    如需資料範本的詳細資訊,請參閱資料範本化概觀

  3. 將現有的 ListBox 取代為下列 XAML:

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

    這個 XAML 會將 ItemsSourceListBox 屬性繫結到資料來源,並套用資料範本作為 ItemTemplate

將資料連接至控制項

接下來,您將新增程式碼來擷取在 ExpenseItHome 頁面上選取的名稱,並將其傳遞至 ExpenseReportPage 的建構函式。 ExpenseReportPage 會以傳遞的元素設定其資料內容,而這就是 ExpenseReportPage.xaml 中定義的控制項繫結的元素。

  1. 開啟 ExpenseReportPage.xaml.vbExpenseReportPage.xaml.cs

  2. 加入一個可接受物件的建構函式,如此您就可以傳遞選取之人員的費用報表資料。

    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;
        }
    }
    
    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
    
  3. 開啟 ExpenseItHome.xaml.vbExpenseItHome.xaml.cs

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

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // View Expense Report
        ExpenseReportPage expenseReportPage = new ExpenseReportPage(this.peopleListBox.SelectedItem);
        this.NavigationService.Navigate(expenseReportPage);
    }
    
    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
    

使用資料範本的樣式資料

在本節中,您會使用資料範本更新資料繫結清單中每個元素的 UI。

  1. 開啟 ExpenseReportPage.xaml

  2. 將「Name」和「Department」這兩個 Label 元素的內容繫結至適當的資料來源屬性。 如需資料繫結的詳細資訊,請參閱資料繫結概觀

    <!-- 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. DataGridTextColumn 元素取代為 DataGrid 元素下的 DataGridTemplateColumn ,並將範本套用至這些元素。 此外,請在 DataGrid 元素中指定 ItemsSource 屬性的值。

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

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

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

應用程式的兩頁頁面都會顯示名稱清單和費用報表。

注意

此範例展示 WPF 的特定功能,且不會遵循安全性、當地語系化和輔助功能等所有最佳做法。 如需 WPF 和 .NET 應用程式開發最佳做法的完整內容,請參閱下列主題:

下一步

在本逐步解說中,您已了解一些使用 Windows Presentation Foundation (WPF) 建立 UI 的技術。 您現在應該對資料繫結 .NET 應用程式的建置組塊有基本的了解。 如需 WPF 架構和程式設計模型的詳細資訊,請參閱下列主題:

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

另請參閱