チュートリアル : WPF デザイナーでの簡単な WPF アプリケーションの作成

更新 : 2010 年 12 月

このチュートリアルでは、WPF デザイナーで簡単な WPF (Windows Presentation Foundation) アプリケーションを作成する方法を示します。

このチュートリアルでは次のタスクを行います。

  • プロジェクトを作成する。

  • レイアウトを作成する。

  • レイアウトにコントロールを追加する。

  • レイアウト関連のプロパティを設定する。

  • データ ソースを作成する。

  • データ ソースに接続する。

  • コントロールのプロパティをバインドする。

ファイル システムを検索できる簡単なアプリケーションを作成します。 アプリケーションのユーザー インターフェイスは、XAML (Extensible Application Markup Language) で実装します。 詳細については、「WPF の XAML」を参照してください。 最終的なアプリケーションを次の図に示します。

FolderExplorer ツリー ビューとリスト ビュー

注意

Visual Studio 2010 内で動作するこのチュートリアルのハンズオン ラボ バージョンは、「WPF Simple Application Walkthrough Hands on Lab (WPF の簡単なアプリケーション チュートリアル ハンズオン ラボ)」に用意されています。

必要条件

このチュートリアルを実行するには、次のコンポーネントが必要です。

  • Visual Studio 2010.

プロジェクトの作成

最初にアプリケーションのプロジェクトを作成します。

プロジェクトを作成するには

  1. Visual Basic または Visual C# で FolderExplorer という名前の新しい WPF アプリケーション プロジェクトを作成します。 詳細については、「方法 : 新しい WPF アプリケーション プロジェクトを作成する」を参照してください。

    WPF デザイナーで MainWindow.xaml が開きます。

  2. デザイン ビューでウィンドウを選択します。 詳細については、「方法 : デザイン画面上で要素を選択して移動する」を参照してください。

  3. [プロパティ] ウィンドウで、Title プロパティの値を Folder Explorer に設定します。

レイアウトの作成

レイアウトは、アプリケーションのメイン ウィンドウでのコントロールの配置を定義します。 ここでは、アプリケーションのコントロールが含まれるレイアウト要素を作成する方法を示します。

レイアウトを作成するには

  1. ウィンドウ上のルート Grid コントロールを選択します。

  2. グリッドに 2 つ目の行を追加します。 詳細については、「方法 : グリッドに行と列を追加する」を参照してください。

  3. グリッドに 2 つ目の列を追加します。

レイアウトへのコントロールの追加

レイアウトを定義したら、ここにコントロールを配置できます。

レイアウトにコントロールを追加するには

  1. [ツールボックス] から、TreeView コントロールをグリッドの最初のセルにドラッグします。

  2. [ツールボックス] から、ListView コントロールを、グリッドの最初の行と 2 つ目の列を占めるセルにドラッグします。

  3. [ツールボックス] から、ListView コントロールを、グリッドの 2 つ目の行と 2 つ目の列を占めるセルにドラッグします。

レイアウト関連のプロパティの設定

ここでは、コントロールのレイアウト関連のプロパティを設定する方法を示します。 各コントロールのプロパティを設定したら、レイアウトは最終的なアプリケーションの図とほぼ同じになります。

レイアウト関連のプロパティを設定するには

  1. TreeView コントロールを選択します。

  2. 以下に示すように、[プロパティ] ウィンドウで、次のプロパティを設定します。

    プロパティ

    Grid.ColumnSpan

    1

    Grid.RowSpan

    2

    高さ

    Auto

    HorizontalAlignment

    Stretch

    Margin

    0,0,0,0

    VerticalAlignment

    Stretch

    Auto

    TreeView コントロールは、最初のグリッド列に収まり、2 つのグリッド行を占めるサイズになります。

  3. 両方の ListView コントロールを選択します。

  4. 以下に示すように、[プロパティ] ウィンドウで、次のプロパティを設定します。

    プロパティ

    Grid.ColumnSpan

    1

    Grid.RowSpan

    1

    高さ

    Auto

    HorizontalAlignment

    Stretch

    Margin

    0,0,0,0

    VerticalAlignment

    Stretch

    Auto

    ListView コントロールは、各グリッド セルに収まるサイズになります。

    デザイン ビュー内のレイアウト

  5. [ドキュメント アウトライン] ウィンドウを開きます。 詳細については、「WPF ドキュメントの要素階層内の移動」を参照してください。

  6. グリッドの ColumnDefinitions ノードを展開します。

  7. 最初の ColumnDefinition 項目を選択します。

    [ドキュメント アウトライン] ウィンドウ

  8. [プロパティ] ウィンドウで、Width プロパティを * に設定します。

  9. [ドキュメント アウトライン] ウィンドウで、2 番目の ColumnDefinition を選択します。

  10. [プロパティ] ウィンドウで、Width プロパティを 2* に設定します。

    列のサイズが変更され、1 番目の列はウィンドウ幅の 3 分の 1、2 番目の列はウィンドウ幅の 3 分の 2 を占めます。

  11. [ドキュメント アウトライン] ウィンドウで、グリッドの RowDefinitions ノードを展開します。

  12. 最初の RowDefinition 項目を選択します。

  13. [プロパティ] ウィンドウで、Height プロパティを * に設定します。

  14. [ドキュメント アウトライン] ウィンドウで、2 番目の RowDefinition を選択します。

  15. [プロパティ] ウィンドウで、Height プロパティを * に設定します。

    行のサイズが変更され、各行がウィンドウの高さの半分を占めます。

  16. ソリューションをビルドして実行します。

  17. ウィンドウのサイズを変更して、TreeView コントロールおよび ListView コントロールのサイズが動的に変わることを確認します。

データ ソースの作成

FolderExplorer アプリケーションのデータ ソースは Folder という名前のクラスです。 このクラスは、シンプルなモデルのファイル システムを提供します。 各 Folder インスタンスが SubFolders コレクションと Files コレクションを持ちます。

データ ソースを作成するには

  1. Folder という名前の新しいクラスを FolderExplorer プロジェクトに追加します。 詳細については、「方法 : 新しいプロジェクト項目を追加する」を参照してください。

  2. この Folder ソース コード ファイルの内容を次のコードに置き換えます。

    Imports System
    Imports System.IO
    Imports System.Linq
    Imports System.Collections.Generic
    Imports System.Collections.ObjectModel
    Imports System.Text
    
    Public Class Folder
        Private _folder As DirectoryInfo
        Private _subFolders As ObservableCollection(Of Folder)
        Private _files As ObservableCollection(Of FileInfo)
    
        Public Sub New() 
            Me.FullPath = "c:\"
    
        End Sub 'New
    
    
        Public ReadOnly Property Name() As String 
            Get
                Return Me._folder.Name
            End Get
        End Property
    
    
        Public Property FullPath() As String 
            Get
                Return Me._folder.FullName
            End Get
    
            Set
                If Directory.Exists(value) Then
                    Me._folder = New DirectoryInfo(value)
                Else
                    Throw New ArgumentException("must exist", "fullPath")
                End If
            End Set
        End Property
    
        ReadOnly Property Files() As ObservableCollection(Of FileInfo)
            Get
                If Me._files Is Nothing Then
                    Me._files = New ObservableCollection(Of FileInfo)
    
                    Dim fi As FileInfo() = Me._folder.GetFiles()
    
                    Dim i As Integer
                    For i = 0 To fi.Length - 1
                        Me._files.Add(fi(i))
                    Next i
                End If
    
                Return Me._files
            End Get
        End Property
    
        ReadOnly Property SubFolders() As ObservableCollection(Of Folder)
    
            Get
                If Me._subFolders Is Nothing Then
                    Try
    
                    Me._subFolders = New ObservableCollection(Of Folder)
    
                        Dim di As DirectoryInfo() = Me._folder.GetDirectories()
    
                        Dim i As Integer
                        For i = 0 To di.Length - 1
                            Dim newFolder As New Folder()
                            newFolder.FullPath = di(i).FullName
                            Me._subFolders.Add(newFolder)
                        Next i
                    Catch ex As Exception
    
                        System.Diagnostics.Trace.WriteLine(ex.Message)
    
                    End Try
                End If
    
                Return Me._subFolders
            End Get
        End Property
    End Class
    
    using System;
    using System.IO;
    using System.Linq;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Text;
    
    namespace FolderExplorer
    {
        public class Folder
        {
            private DirectoryInfo _folder;
            private ObservableCollection<Folder> _subFolders;
            private ObservableCollection<FileInfo> _files;
    
            public Folder()
            {
                this.FullPath = @"c:\";
            }
    
            public string Name
            {
                get
                {
                    return this._folder.Name;
                }
            }
    
            public string FullPath
            {
                get
                {
                    return this._folder.FullName;
                }
    
                set
                {
                    if (Directory.Exists(value))
                    {
                        this._folder = new DirectoryInfo(value);
                    }
                    else
                    {
                        throw new ArgumentException("must exist", "fullPath");
                    }
                }
            }
    
            public ObservableCollection<FileInfo> Files
            {
                get
                {
                    if (this._files == null)
                    {
                        this._files = new ObservableCollection<FileInfo>();
    
                        FileInfo[] fi = this._folder.GetFiles();
    
                        for (int i = 0; i < fi.Length; i++)
                        {
                            this._files.Add(fi[i]);
                        }
                    }
    
                    return this._files;
                }
            }
    
            public ObservableCollection<Folder> SubFolders
            {
                get
                {
                    if (this._subFolders == null)
                    {
                        this._subFolders = new ObservableCollection<Folder>();
    
                        DirectoryInfo[] di = this._folder.GetDirectories();
    
                        for (int i = 0; i < di.Length; i++)
                        {
                            Folder newFolder = new Folder();
                            newFolder.FullPath = di[i].FullName;
                            this._subFolders.Add(newFolder);
                        }
                    }
    
                    return this._subFolders;
                }
            }
        }
    }
    

データ ソースへの接続

WPF コントロールは、データ バインディングによりデータ ソースと接続します。 ここでは、ObjectDataProvider を宣言し、バインドする方法を示します。

データ ソースに接続するには

  1. WPF デザイナーで MainWindow.xaml を開きます。 

  2. XAML ビューで、別の xmlns 割り当てにより、次の XAML を <Window> タグに挿入します。 詳細については、「方法 : 名前空間を XAML にインポートする」を参照してください。

    xmlns:my="clr-namespace:FolderExplorer"
    
  3. 次の XAML を開始 <Window> タグの後で開始 <Grid> タグの前に挿入します。

        <Window.Resources>
    
            <ObjectDataProvider x:Key="RootFolderDataProvider" >
                <ObjectDataProvider.ObjectInstance>
                    <my:Folder FullPath="c:\"/>
                </ObjectDataProvider.ObjectInstance>
            </ObjectDataProvider>
    
            <HierarchicalDataTemplate 
                DataType    = "{x:Type my:Folder}"
                ItemsSource = "{Binding Path=SubFolders}">
                <TextBlock Text="{Binding Path=Name}" />
            </HierarchicalDataTemplate>
    
        </Window.Resources>
    
    
  4. <TreeView> タグを次の XAML に置き換えます。

            <TreeView Grid.ColumnSpan="1" Grid.RowSpan="2" Margin="0,0,0,0" Name="treeView1" >
                <TreeViewItem ItemsSource="{Binding Path=SubFolders, Source={StaticResource RootFolderDataProvider}}" Header="Folders"  />
            </TreeView>
    

コントロールのプロパティのバインディング

コントロールのプロパティを別のコントロールにバインドして、自動プロパティ更新を有効にします。

コントロールのプロパティをバインドするには

  1. XAML ビューで、両方の <ListView> タグを次の XAML に置き換えます。

            <ListView Name="listView1" 
            ItemsSource="{Binding Path=SelectedItem.SubFolders, ElementName=treeView1, Mode=OneWay}" 
            Grid.Column="1" 
            Grid.RowSpan="1" />
    
            <ListView Name="listView2" 
            ItemsSource="{Binding Path=SelectedItem.Files, ElementName=treeView1, Mode=OneWay}" 
            Grid.Column="1" 
            Grid.Row="1" />
    
  2. ソリューションをビルドして実行します。

  3. フォルダー アイテムを展開し、C: ドライブのフォルダーを表示します。

  4. サブフォルダーをクリックし、2 つの ListView コントロールの内容を確認してみてください。

    サブフォルダーは上の ListView コントロールに表示され、ファイルは下の ListView コントロールに表示されます。

次の手順

  • 現在、FolderExplorer アプリケーションが既定のスタイルで表示されています。 独自のスタイルを適用して、アプリケーションの外観と動作を変更できます。

  • Visual Studio には、WPF アプリケーションをデバッグするためのツールが数多く用意されています。 詳細については、「チュートリアル : デザイン時の WPF カスタム コントロールのデバッグ」を参照してください。

参照

処理手順

方法 : 添付イベントを使用する

チュートリアル : デザイン時の WPF カスタム コントロールのデバッグ

概念

分割ビュー : WPF デザイン サーフェイスと XAML を同時に表示する

WPF ドキュメントの要素階層内の移動

その他の技術情報

WPF デザイナーでのコントロールの操作

履歴の変更

日付

履歴

理由

2010 年 12 月

WPF Simple Application Walkthrough Hands on Lab (WPF の簡単なアプリケーション チュートリアル ハンズオン ラボ)」へのリンクが追加されました。

情報の拡充