Windows GUIプログラミング入門5 画面レイアウト(2)、画面遷移(1)

# ■はじめに
今回は画面レイアウトの続きと、別画面の表示の仕方についてやります。

![wbg5-00.png](https://qiita-image-store.s3.amazonaws.com/0/142879/0ff1c875-c506-f380-9041-b90161f9b7a0.png)

[注意]
これまでの回で説明済みの操作方法等は、説明を省略したり簡略化している場合があります。

# ■開発環境
* Windows 10
* Visual Studio Community 2015 Update 3
* .NET Framework 4.x

# ■ドキュメントアウトライン
まず、画面が入り組んでくると便利なツール、ドキュメントアウトラインを表示しておきます。
メニューの「表示」 - 「その他のウィンドウ」 - 「ドキュメントアウトライン」を選択します。
![wbg5-01.png](https://qiita-image-store.s3.amazonaws.com/0/142879/8535029a-9a65-89a7-5475-d2d8be3bd33b.png)

フローティング状態にするなりドッキングするなり好きな場所に配置してください。
コントロールの階層構造がツリー形式で表示でき、ここからコントロールの選択もできます。
![wbg5-02.png](https://qiita-image-store.s3.amazonaws.com/0/142879/d9f980ac-71d8-17b4-7f09-ed39f506f526.png)

# ■Grid

## ◇マウスで行、列分割

Gridを3行、2カラムにします。
ドキュメントアウトラインで`Grid`を選択し、画面デザイナのGrid上端あたりにマウスをポイントしてください。
そうすると黄色い線が表示されるはずなので、大体真ん中あたりでクリックしてください。
![wbg5-03.png](https://qiita-image-store.s3.amazonaws.com/0/142879/ba422b9b-4164-609a-f7a5-e231b3c25f5a.png)

はい、Gridが2カラムになりました。
次にGridの左端の上の方をマウスクリックしてください。
![wbg5-04.png](https://qiita-image-store.s3.amazonaws.com/0/142879/32b73e86-c291-1a45-55b6-c5c73b1e2c38.png)

もう一か所、1行目と同じぐらいの行の高さになるようクリックしてください。
これで3行になります。
![wbg5-05.png](https://qiita-image-store.s3.amazonaws.com/0/142879/039452b1-0024-cf54-8224-21c249833049.png)

# ■メイン画面作成

## ◇ボタンの配置

Gridの1行目左側に`Button`をドラッグ＆ドロップしてください。
![wbg5-06.png](https://qiita-image-store.s3.amazonaws.com/0/142879/012e76b0-4515-28bb-6bd1-f654de9748a9.png)

Gridの1行目右側、3行目左側、3行目右側にそれぞれ`Button`をドラッグ＆ドロップしてください。
![wbg5-07.png](https://qiita-image-store.s3.amazonaws.com/0/142879/a08bb0a5-ba78-52e4-49b5-c39370101e4a.png)

## ◇ボタンのプロパティ設定

画面デザイナで4つのボタンを全て含むよう、対角線上にドラッグしてください。
![wbg5-08.png](https://qiita-image-store.s3.amazonaws.com/0/142879/36bcc6c7-3004-3dfe-f868-ee1d50533688.png)

4つのボタンが選択状態になりました。
![wbg5-09.png](https://qiita-image-store.s3.amazonaws.com/0/142879/82802999-7e47-5455-18c8-0c8d5a0af689.png)

プロパティウィンドウで「レイアウト」カテゴリの`Width`に150、`Height`に30、`HorizonalAlignment`と`VerticalAlignment`に`Center`を設定してください。
![wbg5-10.png](https://qiita-image-store.s3.amazonaws.com/0/142879/a87714b3-b500-05df-0153-44cf9b122019.png)

`Margin`プロパティ右端の`■`をクリックして「リセット」を選択してください。
これでボタン配置時に設定されたMarginプロパティを削除します。
![wbg5-11.png](https://qiita-image-store.s3.amazonaws.com/0/142879/16e2391e-88e0-f840-e688-184a50883d25.png)

`Margin`プロパティが無くなったので、4つのボタンがそれぞれのセルの中央に表示されるようになりました。
![wbg5-12.png](https://qiita-image-store.s3.amazonaws.com/0/142879/fbe7e741-60d7-4eb4-89d1-61f2e4fd928a.png)

`Button`の`Content`プロパティを以下のように設定してください。

```Xml
<Button x:Name="button" Content="ダイアログ１" HorizontalAlignment="Center" VerticalAlignment="Center" Width="150" Height="30"/>
<Button x:Name="button1" Content="ダイアログ２" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Width="150" Height="30"/>
<Button x:Name="button2" Content="次の画面に移動" HorizontalAlignment="Center" Grid.Row="2" VerticalAlignment="Center" Width="150" Height="30"/>
<Button x:Name="button3" Content="新しい画面表示" Grid.Column="1" HorizontalAlignment="Center" Grid.Row="2" VerticalAlignment="Center" Width="150" Height="30"/>

```

## ◇テキストの配置

`TextBlock`を`Grid`の2行目・左側にドラッグ＆ドロップし、
名前（x:Name）に`textBlock`とつけてください。
![wbg5-13.png](https://qiita-image-store.s3.amazonaws.com/0/142879/28e04059-0887-f00a-39b8-abf812163011.png)

# ■ダイアログの作成

## ◇ダイアログ画面作成

新しい項目でウィンドウを1つ追加してください。
名前は`DialogWindow1.xaml`にします。
![wbg5-14.png](https://qiita-image-store.s3.amazonaws.com/0/142879/ccf665fb-67bb-20cd-8b60-5baad1e1cfca.png)

以下のように画面を作成してください。
`Window`の`WindowStyle`プロパティは最小化ボタン・最大化ボタンが無い`ToolWindow`に設定します。
2つのボタンはダブルクリックしてイベントハンドラを設定します。

```Xml:DialogWindow1.xaml
<Window x:Class="WpfApplication5.DialogWindow1"
        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:WpfApplication5"
        mc:Ignorable="d"
        Title="DialogWindow1" Height="150" Width="300" WindowStyle="ToolWindow">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <TextBlock x:Name="clickButtonText" Text="TextBlock" Margin="10"/>

        <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
            <Button Content="OK" Width="80" Margin="0,10,10,10" IsDefault="True" Click="Button_Click"/>
            <Button Content="キャンセル" Width="80" Margin="0,10,10,10" IsCancel="True" Click="Button_Click_1"/>
        </StackPanel>
    </Grid>
</Window>
```

`DialogResult`プロパティに値を設定するとウィンドウが終了します。
処理を確定するような終了の場合は`true`を、キャンセル的な終了の場合は`false`を設定します。

```Csharp:DialogWindow1.xaml.cs（抜粋）
// OK時
private void Button_Click(object sender, RoutedEventArgs e)
{
    this.DialogResult = true;
}

// キャンセル時
private void Button_Click_1(object sender, RoutedEventArgs e)
{
    this.DialogResult = false;
}
```

## ◇ダイアログ表示処理の作成
`MainWindow.xaml`に戻り、`Content`が`ダイアログ１`のボタンをダブルクリックして以下の処理を記述します。
先ほど作成したダイアログを表示する処理です。

```CSharp:MainWindow.xaml.cs（抜粋）
// ウィンドウ生成
var window = new DialogWindow1();
// 生成したウィンドウのテキストに文字列設定
window.clickButtonText.Text = (sender as Button).Content + "が押されました。";
// ウィンドウ表示
bool? res = window.ShowDialog();

// DialogResultをチェック
if (res == true)
{
    textBlock.Text = "OKでダイアログが終了。";
}
else
{
    textBlock.Text = "キャンセルでダイアログが終了。";
}
```

イベント名を右クリックし、「名前の変更」で`dialogButton_Click`に書き換えて「適用」ボタンを押します。
![wbg5-15.png](https://qiita-image-store.s3.amazonaws.com/0/142879/3951c83f-6abd-603c-4566-b5e82e2cbb73.png)

`MainWindow.xaml`のボタン定義で、`Content`が`ダイアログ２`の方にクリックイベントをコピペし、2つのボタンが同じイベントハンドラを呼び出すようにします。

```Xml
<Button x:Name="button" Content="ダイアログ１" HorizontalAlignment="Center" VerticalAlignment="Center" Width="150" Height="30" Click="dialogButton_Click"/>
<Button x:Name="button1" Content="ダイアログ２" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Width="150" Height="30" Click="dialogButton_Click"/>
```

# ■ダイアログ動作確認

ここまでで一度実行してみましょう。

「ダイアログ１」ボタンを押します。
![wbg5-16.png](https://qiita-image-store.s3.amazonaws.com/0/142879/696fdeff-435c-e328-63ca-1c8a894a37d9.png)

ダイアログが表示されました。
呼び出し元のボタンの`Content`がメッセージ部分に表示されています。
`ShowDialog`で表示したウィンドウは閉じるまで呼び出し元の画面には戻れません。
![wbg5-17.png](https://qiita-image-store.s3.amazonaws.com/0/142879/35e58dca-66d3-a446-e336-dfb358c759ce.png)

`OK`ボタンで終了します。
`MainWindow`のテキストが設定されました。
![wbg5-18.png](https://qiita-image-store.s3.amazonaws.com/0/142879/cef467bc-de9a-ce81-dea7-6d63d4c2d64d.png)
次は「ダイアログ２」ボタンを押してみます。

今度も呼び出し元の`Content`がメッセージに反映されています。
![wbg5-19.png](https://qiita-image-store.s3.amazonaws.com/0/142879/d2b53a2b-e4dc-4d76-2c40-69d942233b30.png)
`キャンセル`で閉じてみます。

`MainWindow`のテキストに反映されました。
![wbg5-20.png](https://qiita-image-store.s3.amazonaws.com/0/142879/366b3e45-b96f-132c-a60a-f384558f9e81.png)

# ■別ウィンドウに移動、GridSplitter
新しい項目の追加でウィンドウを追加してください。
名前は`Window1.xaml`にします。

Gridの淵をクリックして3×3に分割します。
縦横中央を細めにしてください。
![wbg5-21.png](https://qiita-image-store.s3.amazonaws.com/0/142879/995eabec-cda6-21e9-cb5e-405a47f674c3.png)

ツールボックスに`g`を入力してフィルタリングし、`GridSplitter`を2つ、ドラッグ＆ドロップしてください。
![wbg5-22.png](https://qiita-image-store.s3.amazonaws.com/0/142879/0bdbc153-cf7c-7a3c-b533-b810bab433f3.png)

`GridSplitter`が配置されました。
![wbg5-23.png](https://qiita-image-store.s3.amazonaws.com/0/142879/118083e0-dff1-4902-79d6-e20b42cb602b.png)

タグを以下のように編集してください。

```Xml
<GridSplitter 
    x:Name="gridSplitter_H"
    Grid.Column="1" Grid.RowSpan="3"
    Width="5"
    HorizontalAlignment="Stretch"/>
<GridSplitter
    x:Name="gridSplitter_V"
    Grid.Row="1" Grid.ColumnSpan="3"
    Height="5"
    HorizontalAlignment="Stretch"/>
```

![wbg5-24.png](https://qiita-image-store.s3.amazonaws.com/0/142879/35e986dc-89a6-8e8e-0c94-6b1eb09c5711.png)

真ん中のカラム幅を調整します。
赤枠のあたりにマウスをポイントしてください。
![wbg5-25.png](https://qiita-image-store.s3.amazonaws.com/0/142879/566c5cda-1643-c280-74c2-67ae4eb95281.png)

ドロップダウンを開いて`Auto`を選択してください。
![wbg5-26.png](https://qiita-image-store.s3.amazonaws.com/0/142879/ab1b4be1-005e-e4b1-ee52-cefd88579cb4.png)

行も同じくGridの真ん中の行、左端あたりにマウスカーソルを持っていき、`Auto`を選択してください。
![wbg5-27.png](https://qiita-image-store.s3.amazonaws.com/0/142879/a11a81fe-fe3e-a588-e399-8b40e433731c.png)

4つのセルに`Rectangle`をドラッグ＆ドロップします。
![wbg5-28.png](https://qiita-image-store.s3.amazonaws.com/0/142879/e97b2b20-01b6-edc6-862d-419579328eaf.png)

タグを以下のように書き換えます。

```Xml
<Rectangle
    Grid.Row="0" Grid.Column="0"
    Fill="Aqua"/>
<Rectangle 
    Grid.Row="0" Grid.Column="2"
    Fill="AntiqueWhite"/>
<Rectangle 
    Grid.Row="2" Grid.Column="0"
    Fill="Aquamarine"/>
<Rectangle
    Grid.Row="2" Grid.Column="2"
    Fill="Blue"/>
```

ボタンを配置し、`Content`を`前の画面に戻る`に設定してください。

![wbg5-29.png](https://qiita-image-store.s3.amazonaws.com/0/142879/f1885379-ae86-7313-cdc0-9047e028b2b0.png)

ボタンをダブルクリックし、Clickのイベントハンドラに以下を入力してください。

```CSharp:「前の画面に戻る」ボタンクリック時の処理
this.Close();
```

ドキュメントアウトラインで`Window`を選択し、プロパティのイベントで`Closing`の欄をダブルクリックします。

![wbg5-30.png](https://qiita-image-store.s3.amazonaws.com/0/142879/da3363f1-82ee-50c9-3612-6c91760775f1.png)

ウィンドウ終了時の処理、Closingイベントに以下の処理を書きます。

```CSharp:Window_Closingの処理
// メイン画面を表示する
App.Current.MainWindow.Show();
```

`MainWindow.xaml`に戻り、「次の画面に移動」ボタンのイベントハンドラを作成します。

```CSharp:「次の画面に移動」ボタンクリック時の処理
// ウィンドウ生成
var window = new Window1();
// ウィンドウ表示
window.Show();
// 自身（MainWindow）を隠す
this.Hide();
```

動かしてみましょう。
「次の画面に移動」ボタンを押します。
![wbg5-31.png](https://qiita-image-store.s3.amazonaws.com/0/142879/d0973002-dfa4-7662-4c0b-d675af6ad7b6.png)

MainWindowが隠れてWindow1が表示されます。
![wbg5-32.png](https://qiita-image-store.s3.amazonaws.com/0/142879/a767eaba-1224-278b-e518-45583fd5dfee.png)

真ん中の部分をドラッグしてサイズを変えられます。
「前の画面に戻る」ボタンを押すとWindow1は終了し、非表示にしていたMainWindowが表示されます。
![wbg5-33.png](https://qiita-image-store.s3.amazonaws.com/0/142879/45e91b84-7be5-f555-5084-eb252933f320.png)

# ■別ウィンドウ表示
普通のウィンドウ表示をやります。
新しい項目の追加でウィンドウを追加してください。
名前はWindow2.xamlにします。

MainWindowの「新しい画面表示」ボタンのイベントハンドラに以下を入力してください。

```CSharp
// ウィンドウ生成
var window = new Window2();
// ウィンドウ表示
window.Show();
```

実行してみます。

「新しい画面表示」ボタンを押すとWindow2がMainWindowの上に表示されます。
ダイアログ表示ではないのでMainWindowも触ることができます。
![wbg5-34.png](https://qiita-image-store.s3.amazonaws.com/0/142879/d1c2dedd-47f7-f466-5400-7f3c95cfbb36.png)

「新しい画面表示」ボタンを何度も押すと、どんどんWindow2が新たに表示されます。
MainWindowとすべてのWindow2を閉じるとプログラムが終了します。
![wbg5-35.png](https://qiita-image-store.s3.amazonaws.com/0/142879/9faf5cf7-948e-d705-f124-d52cdeaeec26.png)

おしまい

---

[＜＜ 最初の記事](http://qiita.com/Kosen-amai/items/f9e3df2aa80363f5af5b "Windows GUIプログラミング入門1 メッセージボックス表示") 　 [＜ 前の記事](http://qiita.com/Kosen-amai/items/af0c4962763f1b587387 "Windows GUIプログラミング入門4 画面レイアウト(1)") 　 [次の記事 ＞](http://qiita.com/Kosen-amai/items/9f5e56e8c80b348b127f "Windows GUIプログラミング入門6 画面遷移(2)")