在這個教學中,你會學習如何使用 Visual Studio 建立 Windows Presentation Foundation(WPF)應用程式。 用 Visual Studio,你可以在視窗中新增控制項並處理事件。 在本教學課程結束時,您有一個簡單的應用程式,可將名稱新增至清單框。
在本教學課程中,您會:
- 建立新的 WPF 應用程式。
- 將控件新增至視窗。
- 處理控制項事件以提供應用程式功能。
- 執行應用程式。
以下是遵循本教學課程時所建立之應用程式的預覽:
先決條件
-
Visual Studio 2026
- 選取 [.NET 桌面開發工作負載]
- 選擇 .NET 10 的獨立元件
建立 WPF 應用程式
建立新應用程式的第一個步驟是開啟 Visual Studio,並從範本產生應用程式。
開啟 Visual Studio。
選取 [建立新專案]。
在 「搜尋範本 」欄位輸入 wpf,等待搜尋結果出現。
在 [程式碼語言] 下拉式清單中,選擇 [C#] 或 [Visual Basic]。
在範本清單中,選擇 WPF 應用程式 ,然後選擇 「下一步」。
這很重要
請勿選取 [WPF 應用程式 (.NET Framework)] 範本。
下圖顯示 C# 和 Visual Basic .NET 專案範本。 如果你套用 程式碼語言 過濾器,對應的範本會被列出。
在 「配置你的新專案 」視窗中,將 專案名稱 設為 「名稱 」,然後選擇 「下一頁」。
你也可以透過調整 位置 路徑,將專案儲存到不同的資料夾。
最後,在 「附加資訊 」視窗中,選擇 .NET 10.0(長期支援) 作為 框架 設定,然後選擇 「建立」。
Visual Studio 產生應用程式後,會開啟預設視窗 MainWindow 的 XAML 設計視窗。 如果看不到設計工具,請按兩下 方案總管 視窗中的MainWindow.xaml檔案,以開啟設計工具。
Visual Studio 的重要部分
Visual Studio 中 WPF 的支援有五個重要元件,您可以在建立應用程式時與其互動:
方案總管
你所有的專案檔案、程式碼、視窗和資源都會出現在這個視窗裡。
屬性
這個視窗會顯示你可以根據所選物品的情境設定屬性設定。 例如,如果你從 解決方案總管中選取一個項目,會顯示與該檔案相關的設定。 若選擇 設計器 中的物件,控制器或視窗的屬性會顯示。
工具箱
工具箱包含您可以新增至設計介面的所有控制項。 要在目前的界面新增控制項,請雙擊滑鼠控制項或拖放控制項到設計器。 通常會改用 XAML 程式代碼編輯器視窗來設計使用者介面(UI),同時使用 XAML 設計工具視窗來預覽結果。
XAML 設計工具
這是 XAML 文件的設計工具。 它是互動式的,而您可以從 [工具箱] 拖放物件。 藉由在設計工具中選取和移動專案,您可以可視化方式撰寫應用程式的 UI。
當設計工具與編輯器都可見時,對於其中一項所做的變更會在另一項中反映出來。
當您在設計工具中選取專案時,[ 屬性 ] 視窗會顯示該物件的相關屬性和屬性。
XAML 程式代碼編輯器
這是 XAML 文件的 XAML 程式碼編輯器。 XAML 程式碼編輯器是不使用設計工具來手動製作 UI 的方法。 在設計工具中加入控件時,設計工具可能會自動設定控件的屬性。 XAML 程式碼編輯器可讓您獲得更多控制力。
當設計工具與編輯器都可見時,對於其中一項所做的變更會在另一項中反映出來。 當您在程式代碼編輯器中巡覽文字插入號時,[ 屬性 ] 視窗會顯示該物件的相關屬性和屬性。
檢查 XAML
建立專案後,XAML 程式碼編輯器會開啟。 它只顯示少量 XAML 程式碼來顯示視窗。 如果編輯器未開啟,請按兩下 方案總管 視窗中的MainWindow.xaml專案。 您應該會看到類似下列範例的 XAML:
<Window x:Class="Names.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Names"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>
這很重要
如果你用 Visual Basic 寫程式,XAML 會稍微不同,特別是屬性。x:Class=".." Visual Basic 中的 XAML 會使用 物件的類別名稱,並將命名空間省略至 類別。
為了進一步瞭解 XAML,讓我們將其細分。 XAML 就是 WPF 處理的 XML 來建立使用者介面。 若要了解 XAML,請至少要熟悉 XML 的基本概念。
檔根 <Window> 目錄代表 XAML 檔案所描述的物件類型。 檔案宣告八個屬性,通常屬於三個類別:
XML 命名空間
XML 命名空間為 XML 提供結構。 它決定你可以在檔案中宣告哪些 XML 內容。
主要
xmlns屬性會匯入整個檔案的 XML 命名空間。 在此情況下,它對應到 WPF 宣告的類型。 其他 XML 命名空間會宣告前置詞,並匯入 XAML 檔案的其他類型和物件。 例如,xmlns:local命名空間會宣告local前置詞,並對應至您的專案所宣告的物件,也就是在Names程式碼命名空間中所宣告的物件。x:Class屬性這個屬性會將 對應
<Window>至程式代碼所定義的類型: MainWindow.xaml.cs 或 MainWindow.xaml.vb 檔案,也就是Names.MainWindowC# 和MainWindowVisual Basic 中的 類別。Title屬性你在 XAML 物件上宣告的任何正常屬性都會設定該物件的屬性。 在本案例中,
Title屬性會設定Window.Title屬性。
變更視窗
在我們的範例應用程式中,此視窗太大,且標題列的描述不夠具體。 讓我們解決那個問題。
首先,按下 F5 鍵或從選單中選擇 除錯>開始除錯 來執行應用程式。
你會看到範本產生的預設視窗,沒有任何控制項,以及一個標題為 MainWindow:
將 設定
Title為Names,以變更視窗的標題。將 設定
Height為180和Width260,以變更視窗的大小。<Window x:Class="Names.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Names" mc:Ignorable="d" Title="Names" Height="180" Width="260"> <Grid> </Grid> </Window>
準備版面配置
WPF 提供功能強大的版面配置系統,其中包含許多不同的版面配置控制項。 版面配置控制項有助於子控制項的放置和大小調整,且甚至可以自動進行。 此 XAML 預設的版面控制項為<Grid>
網格線控件可讓您定義數據列和數據行,就像數據表一樣,並將控件放在特定數據列和數據行組合的界限內。 你可以在格子中加入任意數量的子控制或其他佈局控制。 例如,您可以將另一個 <Grid> 控件放在特定的數據列和數據行組合中,而新的方格接著可以定義更多數據列和數據行,並有自己的子系。
網格線控件會將其子控件放在數據列和數據行中。 方格一律會宣告單一的列和欄,也就是說,方格依預設會是單一儲存格。 這個預設設定讓你在控制鍵放置上彈性不大。
調整此應用程式所需控制件的方格配置。
將新屬性新增至
<Grid>專案:Margin="10"。此設定會從視窗邊緣將網格線帶入,使其看起來更美觀。
定義兩個資料列和兩個數據行,將方格分割成四個數據格:
<Grid Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> </Grid>請在 XAML 程式碼編輯器或 XAML 設計器中選擇格子。 XAML 設計器顯示每一列與欄位:
新增第一個控制項
現在格子已經設定好了,你可以開始為它添加控制項。 首先,加入標籤控制。
在 元素內
<Label>,在數據列和數據行定義之後,建立新的<Grid>專案。 將元素內容設為字串值Names:<Grid Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Label>Names</Label> </Grid><Label>Names</Label>會定義內容Names。 有些控制項了解如何處理內容,有些則不了解。 控制項的內容會對應至Content屬性。 如果你透過 XAML 屬性語法設定內容,請使用以下格式:<Label Content="Names" />。 這兩種方式可以完成相同的作業,設定標籤的內容以顯示文字Names。標籤佔據視窗的一半,因為它自動被定位到格子的第一列和第一欄。 第一排不需要太多空間,因為你只會用那一排來貼標籤。
將第一個
Height的<RowDefinition>屬性從*變更為Auto。Auto值會自動將方格列的大小調整為其內容 (在本案例中,即標籤控制項) 的大小。<Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions>設計工具現在顯示標籤佔據可用高度的一小部分。 下一排有更多空間可以坐。
控制項的放置
讓我們來談談控制項的放置。 你在前一節建立的標籤會自動放在網格的第 0 列和第 0 欄。 數據列和數據行的編號從 0 開始,遞增 1。 控制項不知道方格的任何資訊,而且控制項未定義任何屬性來控制其在方格內的放置位置。
當控制項不了解方格時,要如何指示控制項使用不同的列或欄? 附加屬性! 格網利用了 WPF 提供的屬性系統。
網格線控件會定義子控件可以附加至自己的新屬性。 這些屬性其實不存在於控制元件本身,但一旦加入網格後,它們就可以由該控制元件使用。
方格會定義兩個屬性來判斷子控制項的列和欄放置位置:Grid.Row 和 Grid.Column。 若控制項中省略這些屬性,預設值為 0。 所以,控制元件會放在網格的列 0 和欄 0。 請嘗試將 <Label> 屬性設定為 Grid.Column,以變更 1 控制項的放置位置:
<Label Grid.Column="1">Names</Label>
請注意,標籤已移至第二個數據行。 你可以用附加屬性 Grid.Row 和 Grid.Column 來放置接下來要建立的控制項。 不過,現在請將標籤還原至第 0 欄。
建立名稱清單方塊
方格現已正確調整大小且標籤也已建立,接下來請在標籤下方的列上新增清單方塊控制項。
<ListBox />在控件底下<Label>宣告 控件。將
Grid.Row屬性設定為1。將
x:Name屬性設定為lstNames。一旦控制項被命名,你就可以在程式碼背後引用它。 透過屬性
x:Name將名稱指派給控制項。
XAML 看起來應該像這樣:
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label>Names</Label>
<ListBox Grid.Row="1" x:Name="lstNames" />
</Grid>
新增其餘控制項
新增文字框和按鈕。 使用者利用這些控制項輸入一個名稱,加入清單框。 與其在格子中新增更多列和欄來排列這些控制項,不如把這些控制項放進 <StackPanel> 版面控制項。
堆疊面板與格子面板在放置控制鍵的方式上有所不同。 當你使用 Grid.Row 和 Grid.Column 附加屬性告訴網格布局你想要控制項的位置時,堆疊面板會自動運行。 它依序排列每個子控制項。 它會「堆疊」彼此之後的每個控件。
<StackPanel>在控件底下<ListBox>宣告 控件。將
Grid.Row屬性設定為1。將
Grid.Column屬性設定為1。將
Margin設定為5,0,0,0。<Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Label>Names</Label> <ListBox Grid.Row="1" x:Name="lstNames" /> <StackPanel Grid.Row="1" Grid.Column="1" Margin="5,0,0,0"> </StackPanel>你之前在格子上用過屬性
Margin,但只輸入了一個值。10這個邊界的值與5,0,0,0非常不同10。 margin 屬性是類型,而且可以解譯這兩個Thickness值。 粗細會分別定義矩形框架每一邊 (、左、上、右、下) 的空間。 如果邊界的值是單一值,則四個邊都會使用這個值。在
<StackPanel>控件內,建立<TextBox />控件。- 將
x:Name屬性設定為txtName。
- 將
最後,在
<TextBox>之後,仍然在 內部<StackPanel>,建立<Button>控件。- 將
x:Name屬性設定為btnAdd。 - 將
Margin設定為0,5,0,0。 - 將內容設定為
Add Name。
- 將
XAML 看起來應該像這樣:
<StackPanel Grid.Row="1" Grid.Column="1" Margin="5,0,0,0">
<TextBox x:Name="txtName" />
<Button x:Name="btnAdd" Margin="0,5,0,0">Add Name</Button>
</StackPanel>
視窗的版面配置已完成。 然而,這個應用程式沒有任何邏輯可以真正運作。 接著,你需要把控制事件接到程式碼裡,讓應用程式真正執行某些動作。
新增 Click 事件的程式碼
你建立的 App <Button> 有一個 Click 事件,當使用者按下按鈕時,應用程式會觸發這個事件。 訂閱此活動並新增程式碼,為名單框新增名稱。 用 XAML 屬性訂閱事件,就像用它們設定屬性一樣。
<Button>找出控件。將屬性設定
Click為ButtonAddName_Click。<StackPanel Grid.Row="1" Grid.Column="1" Margin="5,0,0,0"> <TextBox x:Name="txtName" /> <Button x:Name="btnAdd" Margin="0,5,0,0" Click="ButtonAddName_Click">Add Name</Button> </StackPanel>產生事件處理程式程式代碼。 以滑鼠右鍵按一下
ButtonAddName_Click,然後選取 [移至定義]。這個動作會在程式碼後台產生一個與你提供的處理器名稱相符的方法。
private void ButtonAddName_Click(object sender, RoutedEventArgs e) { }Private Sub ButtonAddName_Click(sender As Object, e As RoutedEventArgs) End Sub接下來,新增下列程式碼以執行這三個步驟:
- 確定文字輸入框包含名稱。
- 驗證在文字輸入框中所輸入的名稱不是既存名稱。
- 將該名稱新增至清單方塊。
private void ButtonAddName_Click(object sender, RoutedEventArgs e) { if (!string.IsNullOrWhiteSpace(txtName.Text) && !lstNames.Items.Contains(txtName.Text)) { lstNames.Items.Add(txtName.Text); txtName.Clear(); } }Private Sub ButtonAddName_Click(sender As Object, e As RoutedEventArgs) If Not String.IsNullOrWhiteSpace(txtName.Text) And Not lstNames.Items.Contains(txtName.Text) Then lstNames.Items.Add(txtName.Text) txtName.Clear() End If End Sub
執行應用程式
處理完事件後,啟動應用程式。 視窗會出現,你可以在文字框中輸入名字。 請先選擇按鈕,然後加入名稱。