Windows Presentation Foundation (WPF) の主要なコントロールについて、実際にアプリを作りながら学びます。
今回は、WPFでよく使われる基本的なコントロールの使い方と特徴を学びます。以下の方に役立つ内容となっています。
- WPFのコントロールにどのようなものがあるかを体系的に知りたい方
- WPFで実践的なUI作成を学びたい方
コントロールにどのようなものがあるか体系的に俯瞰した上で、代表的なものをピックアップして具体的に説明します。
演習では、コントロールを組み合わせて以下のようなリスト型メモ帳アプリを作成します。

コントロールはTextBox、Buttonなど、これまでにもでてきましたね。
前回学んだGrid、StackPanelなどのパネルもコントロールの一種です。
今回、あらためてWPFにどのようなコントロールがあるのかを一緒に学んでいきましょう!
演習のコード一式はGitHubに置いてあります。
YouTube動画は以下です。
講義:WPFのコントロール
コントロールの役割
WPFでは、コントロールを使用してユーザインターフェース(UI)を構築します。
コントロールはユーザとアプリの接点となる重要な要素です。
ボタンを押す、テキストを入力する、リストから選択するなど、すべてコントロールを通じて行われます。
コントロールは以下の役割を担います。
- 表示: データや情報をユーザに見やすく表示
- 入力: ユーザからの入力やデータ編集を受け付け
- 操作: クリックや選択などのユーザ操作に応答
- フィードバック: アプリの状態や処理結果をユーザに通知
コントロールの分類と代表例
WPFには多くのコントロールがありますが、機能別に以下のように分類できます。
(Microsoft LearnのWPFカテゴリ別コントロールにおける分類です。)
カテゴリ | 役割 | 代表的なコントロール |
---|---|---|
レイアウト | ボタンやテキストなどの部品を画面上に並べる | Grid、StackPanel、DockPanel、Canvas、Border、Panel、WrapPanel |
ボタン | ユーザがクリックして何かの処理を実行する | Button、RepeatButton |
選択 | 複数の選択肢からユーザが好みのものを選ぶ | CheckBox、ComboBox、ListBox、RadioButton、Slider |
入力 | ユーザがキーボードで文字や数値を入力する | TextBox、RichTextBox、PasswordBox |
データ表示 | 大量のデータを表やリスト形式で見せる | DataGrid、ListView、TreeView |
日付の表示と選択 | カレンダーを表示してユーザが日付を選ぶ | Calendar、DatePicker |
メニュー | 機能をまとめて整理し、ユーザが選択可能にする | ContextMenu、Menu、ToolBar |
ナビゲーション | 画面を切り替えたりページ間を移動する | Frame、Hyperlink、Page、NavigationWindow、TabControl |
ダイアログボックス | ファイルを開く・保存するなどの操作画面を表示 | OpenFileDialog、PrintDialog、SaveFileDialog |
ユーザ情報 | 説明文や進行状況をユーザに分かりやすく表示 | AccessText、Label、Popup、ProgressBar、StatusBar、TextBlock、ToolTip |
ドキュメント | 文書ファイルを画面に表示して読みやすくする | DocumentViewer、FlowDocumentPageViewer、FlowDocumentReader、FlowDocumentScrollViewer、StickyNoteControl |
メディア | 画像・音楽・動画などのファイルを再生・表示 | Image、MediaElement、SoundPlayerAction |
デジタルインク | タブレットペンで手書き文字や絵を描く | InkCanvas、InkPresenter |
すごいたくさんある…!
全部覚える必要はありません。ざっくり、このようなカテゴリがあるという雰囲気を掴んでもらえればOKです。
演習では、これまでで登場してきたGrid(レイアウト系)、Button(ボタン系)、TextBox(入力系)、Label(ユーザ情報系)などの他に、新たに以下のコントロールも使います。
- ListView(データ表示系)
- ComboBox(選択系)
- TabControl(ナビゲーション系)
- Image(メディア系)
これらについてそれぞれ簡単に紹介します。
コントロール紹介
ListView
ListViewはデータを一覧形式で表示するコントロールです。
以下が例です。
<ListView x:Name="ItemListView">
<ListViewItem Content="項目1"/>
<ListViewItem Content="項目2"/>
</ListView>

ListViewは、以下の例のようにクラスオブジェクトを表示することもできます。
<ListView x:Name="MyListView">
<ListView.View>
<GridView>
<GridViewColumn Header="名前" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Header="年齢" DisplayMemberBinding="{Binding Age}"/>
</GridView>
</ListView.View>
</ListView>
C#コードビハインドでListViewに表示するデータを設定します。
...
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// データを作成
var people = new List<Person>
{
new Person { Name = "田中", Age = 30 },
new Person { Name = "佐藤", Age = 25 }
};
// ListViewにデータを設定
MyListView.ItemsSource = people;
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
...

このようにデータ(peopleリスト)とUI(ListView)を直接紐づける方法を「データバインディング」と呼びます。
WPFの特徴的な仕組みの一つで、次回の記事で詳しく解説する予定です。
ComboBox
ComboBoxはドロップダウンリストから選択肢を選ぶコントロールです。
以下が例です。
<ComboBox x:Name="CategoryComboBox">
<ComboBoxItem Content="仕事"/>
<ComboBoxItem Content="個人" IsSelected="True"/>
</ComboBox>

この例では、選択肢(ComboBoxItem)を直接書いています。
ComboBoxもListViewと同様に、ItemsSourceを使ってデータと紐づけて表示することができます。
(たとえば、カテゴリリストをコード側で用意してバインドする、など)
TabControl
TabControlはタブ形式で複数の画面を切り替えるコントロールです。
以下が例です。
<TabControl>
<TabItem Header="メモ">
<!-- メモ入力画面 -->
</TabItem>
<TabItem Header="設定">
<!-- 設定画面 -->
</TabItem>
</TabControl>

Image
Imageは画像を表示するコントロールです。以下が例です。
<Image Source="images/prota.png"/>

画像ファイルを適切な場所へ配置する必要があります。配置方法については演習で詳しく解説します。
演習:様々なコントロールを使ったアプリ
作成するアプリの概要
主要コントロールを組み合わせて、以下の機能を持つ「リスト型メモ帳アプリ」を作成します。
- アプリロゴを画面に表示
- カテゴリを選択してメモを入力
- 入力したメモ(カテゴリ付き)の一覧を表示
- タブによる「メモ画面」と「設定画面」の切り替え
(今回、設定画面はダミーです)
様々なカテゴリからピックアップした、以下のようなコントロールを使います。
- Grid – 基本レイアウト
- Button – メモ追加ボタン
- TextBox – メモ入力欄
- ListView – メモ一覧表示
- ComboBox – カテゴリ選択
- TabControl – 画面切り替え
- Label – 各種ラベル表示
- Image – アプリロゴ
以下の手順で作成します。
- 手順1:画面作成(XAML)
- 手順2:イベント作成(C#コードビハインド)
- 手順3:ロゴ画像の配置とプロジェクトファイル修正
「画面(XAML)→イベント(C#コード)」のところは、WPFアプリ開発のいつもの手順だね!
手順1:画面作成(XAML)
WPFの新規プロジェクトを作成します。作成方法は以下の記事の手順2を参考にしてください。

「MainWindow.xaml」を以下のように修正します。

<Window x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- 上部:ロゴとタイトル -->
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,0,0,10">
<!-- Image: アプリロゴ -->
<Image Source="images/logo.png" Width="40" Height="40" Margin="0,0,10,0"/>
<!-- Label: アプリタイトル -->
<Label Content="リスト型メモ帳アプリ" FontSize="18" FontWeight="Bold"
VerticalAlignment="Center"/>
</StackPanel>
<!-- TabControl: メインエリア -->
<TabControl Grid.Row="1">
<!-- メモ入力・表示タブ -->
<TabItem Header="メモ">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- 入力エリア -->
<StackPanel Grid.Row="0" Margin="0,0,0,10">
<!-- Label: 入力ラベル -->
<Label Content="新しいメモ:" FontWeight="Bold"/>
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
<!-- TextBox: メモ入力 -->
<TextBox x:Name="MemoTextBox" Width="180" Margin="0,0,10,0"
Text="ここにメモを入力"/>
<!-- ComboBox: カテゴリ選択 -->
<ComboBox x:Name="CategoryComboBox" Width="70" Margin="0,0,10,0">
<ComboBoxItem Content="仕事" IsSelected="True"/>
<ComboBoxItem Content="個人"/>
<ComboBoxItem Content="買い物"/>
</ComboBox>
<!-- Button: 追加ボタン -->
<Button Content="追加" Click="OnAddButtonClick"/>
</StackPanel>
</StackPanel>
<!-- ListView: メモ一覧 -->
<ListView x:Name="MemoListView" Grid.Row="1">
<ListViewItem Content="サンプルメモ1 (仕事)"/>
<ListViewItem Content="サンプルメモ2 (個人)"/>
</ListView>
</Grid>
</TabItem>
<!-- 設定タブ -->
<TabItem Header="設定">
<StackPanel Margin="20">
<!-- Label: 設定タイトル -->
<Label Content="アプリ設定" FontSize="14" FontWeight="Bold"/>
<CheckBox Content="起動時にメモを自動読み込み" IsChecked="True" Margin="0,10,0,5"/>
<CheckBox Content="終了時に確認ダイアログを表示" IsChecked="False" Margin="0,5,0,10"/>
</StackPanel>
</TabItem>
</TabControl>
</Grid>
</Window>
これまで紹介してきたコントロールやプロパティを中心に使っています。ポイントは以下です。
- Grid.RowDefinitions: Autoで上部のロゴ・タイトル領域を最小サイズに、*でTabControl領域を残り全体に配置
- StackPanel: 横並び(Horizontal)でロゴ画像とタイトルラベルを配置
- Image: ロゴ画像を表示
- TabControl: メモタブと設定タブの2画面を切り替え可能に構成
- ListView: 初期状態でサンプルメモを表示、後からC#コードで動的に項目追加
- ComboBox: 「仕事」「個人」「買い物」の3つのカテゴリから選択可能、「仕事」を初期選択に設定
手順2:イベント作成(C#コードビハインド)
次に「MainWindow.xaml.cs」を以下のように修正します。

...
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
// イベントハンドラ: ボタンがクリックされたときに呼び出される
private void OnAddButtonClick(object sender, RoutedEventArgs e)
{
// TextBox: 入力されたメモを取得
string memo = MemoTextBox.Text;
// ComboBox: 選択されたカテゴリを取得
string? category = (CategoryComboBox.SelectedItem as ComboBoxItem)?.Content.ToString();
if (!string.IsNullOrWhiteSpace(memo))
{
// ListView: 新しいメモを追加
MemoListView.Items.Add($"{memo} ({category})");
// TextBox: 入力欄をクリア
MemoTextBox.Clear();
}
}
}
...
ポイントは以下です。
- OnAddButtonClick: ボタンクリック時にTextBoxとComboBoxから値を取得し、ListViewに新しい項目を追加
- 入力値の検証: string.IsNullOrWhiteSpaceで空文字チェックを行い、有効な入力のみ処理
- UI更新: メモ追加後にTextBoxをクリアして次の入力に備える
- ComboBoxの値取得: SelectedItemをComboBoxItemにキャストしてContentプロパティから文字列を取得
手順3:ロゴ画像配置とプロジェクトファイル修正
最後にロゴ画像ファイルを用意し、その画像ファイルがデバッグビルド時に、デバッグ用のバイナリファイルのフォルダへ自動で配置されるようにしましょう。
まず、WpfApp1プロジェクトフォルダ直下にimagesフォルダを作成し、そこへロゴ画像(ここではlogo.png)を配置します。
...
└─WpfApp1
│ App.xaml
│ App.xaml.cs
│ AssemblyInfo.cs
│ MainWindow.xaml
│ MainWindow.xaml.cs
│ WpfApp1.csproj
│
├─images
│ logo.png
...
imagesフォルダ作成やロゴ画像の配置は、Windowsのファイルエクスプローラ上で直接行ってOKです!
次に、プロジェクトファイルを直接編集し、ビルド時にデバッグ用バイナリと同じフォルダにこのimagesフォルダが自動でコピーされるよう設定を追加します。
Visual Studioのソリューションエクスプローラで「WpfApp1(プロジェクト)」を選び、右クリックメニューを開きます。

「プロジェクトの編集」を選びます。

以下のように、「<ItemGroup>…</ItemGroup>」の記述を追加します。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<Content Include="images\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
これで、imagesフォルダがビルド時にデバッグ用バイナリが配置されたフォルダ(例:WpfApp1\bin\Debug\net9.0-windows)へコピーされるようになります。
プロジェクトファイル(WpfApp1.csproj)の中身を、直接編集しているんだね!
ビルド後に、デバッグ用バイナリが配置されたフォルダ内を確認すると、imagesフォルダ(と中身の画像)がコピーされていることが確認できます。

C#におけるプロジェクト構成や、実行用バイナリファイルの配置などについては、以下でも触れて解説していますので、参考にしてください。

これで一通りできました!動かしてみましょう。
アプリを実行
アプリをデバッグ実行してみましょう。リストへのメモ追加がきます。

タブ切り替えで(ダミーですが、)設定も開けます。

色々なコントロールを使ったアプリができたね!
簡単なアプリではありますが、今回はWPFの様々な系統のコントロールの使い方・雰囲気を掴んでもらえればOKです!
まとめ
本記事では、WPFの主要コントロールを使った実践的なアプリ開発について学びました。
WPFのコントロールには以下の特徴と利点があります。
- 豊富な種類:レイアウト、ボタン、選択、入力、データ表示など、10以上のカテゴリに分類される多様なコントロールが用意されている
- 柔軟な組み合わせ:Gridなどのレイアウトコントロールと、Button、ListViewなどの機能コントロールを組み合わせて、複雑なUIを構築できる
リスト型メモ帳アプリの演習を通じて、以下のような様々な系統のコントロールを組み合わせて使う方法を学びました。
- Grid(レイアウト系)
- Button(ボタン系)
- TextBox(入力系)
- Label(ユーザ情報系)
- ListView(データ表示系)
- ComboBox(選択系)
- TabControl(ナビゲーション系)
- Image(メディア系)
ここまでで、XAML・C#コードビハインド、そしてレイアウトを含めた様々なコントロールの使い方といったWPFアプリ開発の基礎について学んでいきました。
次回は、WPFの特徴的な機能の1つである「データバインディング」について解説する予定です。
引き続き、一緒にWPFアプリ開発を学んでいきましょう!