WPFプロジェクトの作り方と基礎知識

WPFプロジェクトの作り方とWPFに関連する基礎的な情報です。

プロジェクトを作成する

Visual Studioを起動して、下記の手順でプロジェクトを作成できます。

  1. ファイル > 新規作成 > プロジェクト
  2. インストール済み > Visual C# > WPFアプリ

以下のような画面が表示されるので、開始ボタンを押して
真っ白なウィンドウが表示されればプロジェクトが正常に作れています。

f:id:halya_11:20180925135748p:plain

上記の画面が出てこない場合

前節の画像のようにWPFアプリが選択肢として出てこない場合はインストールする必要があります。
まずVisual Studioインストーラを開きます。

f:id:halya_11:20180907134224p:plain

.Netデスクトップ開発をインストールします。

f:id:halya_11:20180907134317p:plain

これでWPFアプリのプロジェクトが作れるようになったはずです。

アプリ起動時の処理の流れ

作りたてのWPFアプリはこんな感じの構成になっています。

f:id:halya_11:20180925140107p:plain

アプリを起動すると、内部的にMainメソッド内でAppクラスのインスタンスが生成されます。
さらにAppクラスのRun()メソッドが呼ばれます。

このRun()では「App.xamlで指定されているWindowを表示する」という処理がされます。
そこで、App.xamlを見ると下記のような記述があります。

StartupUri="MainWindow.xaml"

これに従い今度はMainWindow.xaml.csというクラスを見てみます。
すると、コンストラクタでInitializeComponent()が呼ばれていることがわかります。

namespace WpfApp1
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

つまりここに処理を書いていけば、起動時にその処理が実行されることになります。

.xamlと.xaml.csの関係性

前節の画像を見ると、MainWindowに関連するファイルとして
MainWindow.xamlとMainWindow.xaml.csがあることがわかります。

WPFではこのようにxamlファイルと、それと対になるcsファイルが生成されます。
そしてレイアウトをxamlファイルに、ロジックをcsファイルに定義します。

最終的にこれら二つのファイルは1つのクラスとしてコンパイルされます。

XAMLとは何か?

XAMLファイルとは、インスタンスシリアライズしたものです。
挙動を見たほうが早いのでXAMLファイルを生成するコードを書いてみます。

using System.Windows;
using System.IO;
using System.Windows.Markup;

namespace WpfApp1
{
    public class Sample
    {
        public int SampleInt { get; set; }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            
            var sample = new Sample{ SampleInt = 100 };
            using (var stream = File.Open("sample.xaml", FileMode.Create)) {
                XamlWriter.Save(sample, stream);
            }
        }
    }
}

これを実行すると次のようなXAMLファイルが生成されます。

<Sample SampleInt="100" xmlns="clr-namespace:WpfApp1;assembly=WpfApp1" />

オブジェクトがシリアライズされた情報であることがわかります。

もちろん次のようにして読み込みも行えます。

using System.Windows;
using System.IO;
using System.Windows.Markup;
using System;

namespace WpfApp1
{
    public class Sample
    {
        public int SampleInt { get; set; }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            
            using (var stream = File.Open("sample.xaml", FileMode.Open)) {
                var s = XamlReader.Load(stream) as Sample;
                Console.WriteLine(s.SampleInt);
            }
        }
    }
}

UIを配置する

UIを配置するにはXamlファイルを開いた状態で左のツールボックスからWPFコントロールを選択します。
ここではMainWindowにButtonを適当に配置します。

f:id:halya_11:20180925143504p:plain

この変更によりMainWindow.xamlにはGridとButtonが追加されました。

<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>
        <Button Content="Button" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75"/>
    </Grid>
</Window>

再生するとボタンだけ配置されたウィンドウが表示されます。

f:id:halya_11:20180925143712p:plain

UIをコードから生成してみる

XAMLの仕組みをもう少し知るために、UIをコードから生成してみます。

前節のXamlファイルのGridの部分を以下のように書き換えて名前を付け、Buttonを削除してみます。

<Grid x:Name="grid">
</Grid>

するとcsファイルの方からgridというフィールドにアクセスできるようになるので、
これの子要素としてButtonを生成します。

using System.Windows;
using System.Windows.Controls;

namespace WpfApp1
{
    public class Sample
    {
        public int SampleInt { get; set; }
    }

    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            grid.Children.Add(new Button{
                Content             = "Button",
                HorizontalAlignment = HorizontalAlignment.Left,
                Margin              = new Thickness(10, 10, 0, 0),
                VerticalAlignment   = VerticalAlignment.Top,
                Width               = 75
            });
        }
    }
}

再生結果は前節のものと同じになり、コードからUIを生成できました。

参考

www.atmarkit.co.jp

www.atmarkit.co.jp