這篇文章演示如何開發簡單的 Windows Presentation Foundation (WPF) 應用程序包括元素所共有的大多數 WPF 應用程序: 可擴展應用程序標記語言 (XAML) 標記、 代碼隱藏、 應用程序定義控件、 佈局、 數據綁定和樣式。git
本演練包含如下步驟:github
使用 XAML 設計應用程序的用戶界面 (UI) 的外觀。express
編寫代碼以生成應用程序的行爲。編程
建立應用程序定義管理應用程序。canvas
添加控件並建立佈局以構成應用程序 UI。windows
建立在應用程序的 UI 整個一致的外觀樣式。api
綁定到數據填充數據從用戶界面的同時保護數據和 UI 同步的用戶界面。瀏覽器
本演練結束時,您將構建的獨立 Windows 應用程序,用戶可查看所選人員的費用報銷。 該應用程序由多個瀏覽器樣式窗口中承載的 WPF 頁面。安全
提示app
用於生成本演練的示例代碼是適用於 Visual Basic 和 C# 在生成 WPF 應用程序簡介。
有關安裝最新版本的 Visual Studio 的詳細信息,請參閱安裝 Visual Studio。
第一步是建立應用程序基礎結構,其中包括應用程序定義、 兩個頁面和映像。
建立新的 WPF 應用程序項目中 Visual Basic 或 Visual C# 名爲ExpenseIt:
打開 Visual Studio 並選擇文件 > 新建 > 項目。
新項目對話框隨即打開。
下已安裝類別中,展開Visual C# 或Visual Basic節點,,而後選擇Windows 經典桌面。
選擇WPF 應用程序 (.NET Framework) 模板。 輸入的名稱ExpenseIt ,而後選擇肯定。
Visual Studio 建立項目並打開名爲的默認應用程序窗口的設計器MainWindow.xaml。
備註
本演練使用DataGrid可用在.NET Framework 4 和更高版本的控件。 爲確保你的項目面向.NET Framework 4 或更高版本。 有關詳細信息,請參閱如何:面向 .NET Framework 的某個版本。
打開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>
打開MainWindow.xaml。
此 XAML 文件是你的應用程序的主窗口,並顯示在頁中建立的內容。 Window類定義的屬性窗口中,例如,其標題、 大小或圖標,並處理事件,例如關閉或隱藏。
更改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須要更改成NavigationWindow。 NavigationWindow 繼承的全部屬性Window。 NavigationWindow XAML 文件中的元素建立的實例NavigationWindow類。 有關詳細信息,請參閱導航概述。
在更改下列屬性NavigationWindow元素:
設置Title屬性設置爲"ExpenseIt"。
設置Width爲 500 像素的屬性。
設置Height爲 350 像素的屬性。
刪除Grid之間的元素NavigationWindow標記。
在 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>
打開MainWindow.xaml.vb或MainWindow.xaml.cs。
此文件是包含代碼來處理中聲明的事件的代碼隱藏文件MainWindow.xaml。 此文件包含在 XAML 中定義的窗口的分部類。
若是你使用的 C#,更改MainWindow
類以派生自NavigationWindow。 (在 Visual Basic 中,自動發生此狀況時更改 XAML 中的窗口。)
你的代碼應以下所示:
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(); } } }
提示
您能夠切換之間 C# 和 Visual Basic 中的示例代碼的代碼語言語言這篇文章右上方的下拉列表。
本部分將嚮應用程序添加兩個頁面和一個圖像。
將新的 WPF 頁添加到項目中,並將其命名ExpenseItHome.xaml:
在解決方案資源管理器,右鍵單擊ExpenseIt項目節點,選擇添加 > 頁。
在添加新項對話框中,頁 (WPF) 還沒有選擇模板。 輸入的名稱ExpenseItHome,而後選擇添加。
此頁是啓動應用程序時顯示的第一頁。 它將顯示要選擇,從顯示的支出報表的人員列表。
打開 ExpenseItHome.xaml。
設置Title到"ExpenseIt-主頁"。
在 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="300" d:DesignWidth="300" 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="300" d:DesignWidth="300" Title="ExpenseIt - Home"> <Grid> </Grid> </Page>
打開MainWindow.xaml。
設置Source屬性NavigationWindow到"ExpenseItHome.xaml"。
這將 ExpenseItHome.xaml 設置爲應用程序啓動時第一個打開的頁。 在 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" 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>
提示
你還能夠設置源中的屬性雜項類別屬性窗口。
將另外一個新的 WPF 頁添加到項目中,並將其命名ExpenseReportPage.xaml::
在解決方案資源管理器,右鍵單擊ExpenseIt項目節點,選擇添加 > 頁。
在添加新項對話框中,頁 (WPF) 還沒有選擇模板。 輸入的名稱ExpenseReportPage,而後選擇添加。
此頁會顯示費用報表上所選的人員ExpenseItHome頁。
打開 ExpenseReportPage.xaml。
設置Title到"ExpenseIt-View Expense"。
在 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="300" d:DesignWidth="300" 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="300" d:DesignWidth="300" Title="ExpenseIt - View Expense"> <Grid> </Grid> </Page>
打開ExpenseItHome.xaml.vb和ExpenseReportPage.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(); } } }
和以下有關ExpenseReport:
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(); } } }
添加了名爲映像watermark.png到項目。 您能夠建立本身的映像,示例代碼中的文件複製或獲取它此處。
右鍵單擊項目節點並選擇添加 > 現有項,或按Shift+Alt+ A。
在添加現有項對話框中,瀏覽到你想要使用,而後選擇映像文件添加。
若要生成並運行應用程序,請按F5或選擇啓動調試從調試菜單。
下圖顯示具備的應用程序NavigationWindow按鈕:
關閉應用程序返回到 Visual Studio。
佈局提供有序的方式來放置 UI 元素,並還管理的大小和位置,這些元素的 UI 調整大小時。 一般使用如下佈局控件之一來建立佈局:
每一個佈局控件都爲子元素支持特殊類型的佈局。 ExpenseIt 頁面可進行調整,而且每一個頁面均有與其餘元素水平或垂直排列的元素。 所以,Grid是應用程序的理想佈局元素。
在部分中,你建立一個單列的表具備三個行和 10 像素邊距經過添加到的列和行定義Grid中ExpenseItHome.xaml。
打開 ExpenseItHome.xaml。
設置Margin屬性Grid"10,0,10,10",對應於左側、 頂部、 右側和底部邊距的元素:
<Grid Margin="10,0,10,10">
提示
你還能夠設置邊距中值屬性窗口下佈局類別:
將如下 XAML 之間添加Grid標記以建立行和列定義:
<Grid.ColumnDefinitions> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition /> <RowDefinition Height="Auto"/> </Grid.RowDefinitions>
Height的兩個行設置爲Auto,行大小將調整這意味着根據行中的內容。 默認值Height是Star調整大小,這意味着行高度的可用空間的加權的比例。 例如,若是兩個行具備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:
每一個控件所在的行中Grid經過設置Row附加屬性。 有關附加屬性的詳細信息,請參閱附加屬性概述。
打開 ExpenseItHome.xaml。
添加如下 XAML 某處,之間Grid標記:
<!-- 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>
提示
你還能夠經過將其從拖動建立控件工具箱窗口拖到設計窗口中,而後設置其屬性屬性窗口。
生成並運行應用程序。
下圖顯示了剛建立的控件:
在此部分中,你將使用的映像和頁面標題更新主頁 UI。
打開 ExpenseItHome.xaml。
添加到另外一列ColumnDefinitions帶有固定Width爲 230 像素:
<Grid.ColumnDefinitions> <ColumnDefinition Width="230" /> <ColumnDefinition /> </Grid.ColumnDefinitions>
添加到另外一個行RowDefinitions,四行的總計的:
<Grid.RowDefinitions> <RowDefinition/> <RowDefinition Height="Auto"/> <RowDefinition /> <RowDefinition Height="Auto"/> </Grid.RowDefinitions>
將控件移至第二列中,經過設置Column爲 1 每三個控件 (邊框、 列表框中和按鈕) 中的屬性。
每一個控件下移一行時,經過將遞增其Row值加 1。
這三個控件的 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>
設置Background的Grid要watermark.png圖像文件,請經過添加之間如下某個位置的 XAML<Grid>
和<\/Grid>
標記:
<Grid.Background> <ImageBrush ImageSource="watermark.png"/> </Grid.Background>
以前Border元素中,添加Label"查看費用報表"的內容。 這是頁的標題。
<Label Grid.Column="1" VerticalAlignment="Center" FontFamily="Trebuchet MS" FontWeight="Bold" FontSize="18" Foreground="#0066cc"> View Expense Report </Label>
生成並運行應用程序。
下圖顯示您剛添加的結果:
打開 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>
打開 ExpenseItHome.xaml.vb 或 ExpenseItHome.xaml.cs。
如下代碼添加到ExpenseItHome
類添加一個按鈕單擊事件處理程序。 事件處理程序將打開ExpenseReportPage頁。
private void Button_Click(object sender, RoutedEventArgs e) { // View Expense Report ExpenseReportPage expenseReportPage = new ExpenseReportPage(); this.NavigationService.Navigate(expenseReportPage); }
ExpenseReportPage.xaml上所選的人員顯示費用報表ExpenseItHome頁。 在本部分中,能夠將控件和建立用於 UI ExpenseReportPage。 你將添加背景,並填充到各類 UI 元素的顏色。
打開 ExpenseReportPage.xaml。
將如下 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" 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。
生成並運行應用程序。
備註
若是收到錯誤DataGrid找不到或不存在,請確保你的項目面向.NET Framework 4 或更高版本。 有關詳細信息,請參閱如何:面向 .NET Framework 的某個版本。
選擇視圖按鈕。
出現費用報告頁。 另請注意啓用了向後導航按鈕。
下圖顯示添加到 UI 元素ExpenseReportPage.xaml。
各類元素的外觀一般是相同的 UI 中的相同類型的全部元素。 UI 使用樣式以使多個元素的外觀可重複使用。 可重用性的樣式可幫助簡化 XAML 建立和管理。 本部分替換在之前步驟中經過樣式定義的按元素劃分的屬性。
打開Application.xaml或App.xaml。
將如下 XAML 之間添加Application.Resources標記:
<!-- 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
: 若要設置格式ButtonExpenseItHome.xaml 上。
請注意,樣式是資源和子級Application.Resources屬性元素。 在此位置中,這些樣式將應用到應用程序中的全部元素。 有關在.NET Framework 應用程序中使用資源的示例,請參閱使用應用程序資源。
打開 ExpenseItHome.xaml。
替換之間的全部內容Grid使用如下 XAML 元素:
<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>
應用樣式會刪除和替換定義每一個控件外觀的屬性(如 VerticalAlignment 和 FontFamily 。 例如,headerTextStyle
應用於"查看費用報表" Label。
打開 ExpenseReportPage.xaml。
替換之間的全部內容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" 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>
在此部分中,你將建立綁定到各類控件的 XML 數據。
打開 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資源。 這一般會做爲文件加載,但爲簡單起見數據之內聯方式添加。
在<Grid.Resources>
元素中,添加如下DataTemplate,它定義如何顯示中的數據ListBox:
<Grid.Resources>
<!-- Name item template --> <DataTemplate x:Key="nameItemTemplate"> <Label Content="{Binding XPath=@Name}"/> </DataTemplate>
</Grid.Resources>
有關數據模板的詳細信息,請參閱數據模板化概述。
將現有ListBox使用如下 XAML:
<ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2" ItemsSource="{Binding Source={StaticResource ExpenseDataSource}, XPath=Person}" ItemTemplate="{StaticResource nameItemTemplate}"> </ListBox>
此 XAML 將綁定ItemsSource屬性ListBox到數據源並應用數據模板做爲ItemTemplate。
接下來,將添加代碼以檢索選擇的名稱ExpenseItHome頁上,並將其傳遞給構造函數的ExpenseReportPage。 ExpenseReportPage設置與所傳遞的項目,這是控件定義其數據上下文中ExpenseReportPage.xaml將綁定到。
打開 ExpenseReportPage.xaml.vb 或 ExpenseReportPage.xaml.cs。
添加獲取對象的構造函數,以便傳遞所選人員的費用報表數據。
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; } }
打開 ExpenseItHome.xaml.vb 或 ExpenseItHome.xaml.cs。
更改Click事件處理程序以調用新的構造函數傳遞所選人員的費用報表數據。
private void Button_Click(object sender, RoutedEventArgs e) { // View Expense Report ExpenseReportPage expenseReportPage = new ExpenseReportPage(this.peopleListBox.SelectedItem); this.NavigationService.Navigate(expenseReportPage); }
在此部分中,你將使用數據模板更新數據綁定列表中每一個項的 UI。
打開 ExpenseReportPage.xaml。
將綁定的內容的"名稱"和"部門"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>
在起始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>
應用到模板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>
生成並運行應用程序。
選擇 person,而後選擇視圖按鈕。
下圖顯示控件、 佈局、 樣式、 數據綁定和數據模板的 ExpenseIt 應用程序的兩個頁面:
備註
此示例演示了 WPF 的特定功能,並不遵循全部最佳實踐安全、 本地化和可訪問性之類的內容。有關 WPF 和.NET Framework 應用程序開發最佳作法的全面介紹,請參閱如下主題:
在本演練中你學習了大量的用於建立使用 Windows Presentation Foundation (WPF) UI 技術。 你應該已經基本瞭解數據綁定,.NET Framework 應用程序的構建基塊。 有關 WPF 體系結構和編程模型的詳細信息,請參閱如下主題:
有關建立應用程序的詳細信息,請參閱如下主題:
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
App.xaml
<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>
<!-- 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>
</Application.Resources>
</Application>
App.xaml.cs
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace ExpenseIt
{
/// <summary>
/// App.xaml 的交互邏輯
/// </summary>
public partial class App : Application
{
}
}
ExpenseItHome.xaml
<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="300" d:DesignWidth="300"
Title="ExpenseIt - Home">
<Grid Margin="10,0,10,10" Width="780" Height="440">
<Grid.Resources>
<!-- Name item template -->
<DataTemplate x:Key="nameItemTemplate">
<Label Content="{Binding XPath=@Name}"/>
</DataTemplate>
<!-- 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.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"
ItemsSource="{Binding Source={StaticResource ExpenseDataSource}, XPath=Person}"
ItemTemplate="{StaticResource nameItemTemplate}">
</ListBox>
<!-- View report button -->
<Button Grid.Column="1" Grid.Row="3" Click="Button_Click" Style="{StaticResource buttonStyle}">View</Button>
</Grid>
</Page>
ExpenseItHome.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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>
/// ExpenseItHome.xaml 的交互邏輯
/// </summary>
public partial class ExpenseItHome : Page
{
public ExpenseItHome()
{
InitializeComponent();
}
//一個xaml至關於一個類
private void Button_Click(object sender, RoutedEventArgs e)
{
// View Expense Report
ExpenseReportPage expenseReportPage = new ExpenseReportPage(this.peopleListBox.SelectedItem);
this.NavigationService.Navigate(expenseReportPage);
}
}
}
ExpenseReportPage.xaml
<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="300" d:DesignWidth="300"
Title="ExpenseIt-View Expense">
<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>
<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}" 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>
<Grid Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" VerticalAlignment="Top"
HorizontalAlignment="Left">
<!-- 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>
</Grid>
</Grid>
</Grid>
</Page>
ExpenseReportPage.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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>
/// ExpenseReportPage.xaml 的交互邏輯
/// </summary>
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;
}
}
}
MainWindow.xaml
<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>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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> /// MainWindow.xaml 的交互邏輯 /// </summary> public partial class MainWindow : NavigationWindow { public MainWindow() { InitializeComponent(); } }}