.NET Core 3.1 GUIコントロール

# ■はじめに

`.NET Core 3.1`と`Visual Studio`で基本的なコントロールを使ってみます。

# ■環境

* Windows 10
* Visual Studio 2019
* .NET Core 3.1

# ■画面作成

まず、[こちら](https://qiita.com/Kosen-amai/items/a8df0f4acc877a249297 ".NET Core 3.1とVisual Studioでデスクトップアプリ") を参考に「準備」と「プロジェクトの作成」をしてください。

そして以下のようにコントロールを配置し、コードを書きます。

![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/14aa2815-19fe-bf4f-c5cb-3f05ad2596ab.png)

## ◇コントロール

### Button（ボタン）

普通のボタンです。

サンプルでは押すとメッセージボックスを表示します。
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/ca6b7082-7f79-9fe5-a9c7-caa6fb9fea67.png)

### RepeatButton（リピートボタン）

長押しボタン（繰り返しボタン）です。押している間、クリックイベントが連続して発生します。
ツールボックスには表示されていないのでタグ手打ちで追加します。

サンプルでは押している間、タイトルバーに★を追加し続けます。
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/aa466335-9375-1a59-0e04-08d2e00dfa98.png)

### ToggleButton（トグルボタン）

ON/OFFを表せるボタンです。通常の状態と押されたままの状態をとることができます。
機能的にチェックボックスでも代用できます。
ツールボックスには表示されていないのでタグ手打ちで追加します。

![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/e8f6ec6e-669c-f24d-a756-3a0018520b0c.png)

### CkeckBox（チェックボックス）

トグルボタンと同様、チェックが付いた状態とチェックなしの状態をとることができます。
![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/ece9f4f4-324d-3516-8d16-006e19f0c5cc.png)

### ComboBox（コンボボックス）

複数の選択肢の中から項目を選択できます。
ドロップダウンリストは通常閉じているので省スペースです。
![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/b59823c2-9a45-1d75-cfd3-5bb5e9edf653.png)

### ListBox（リストボックス）

スペースに余裕がある場合はコンボボックスよりこちらの方がリストを開く手間が省けます。
![007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/0d172037-1890-9e04-76fd-685e11c7c700.png)

### Label（ラベル）

表示用のテキストコントロールです。
項目の名前表示などに使います。
![008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/c34ad398-689c-fbd1-520b-66ce306a66c3.png)

### TextBox（テキストボックス）

テキスト入力用のコントロールです。
![009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/3bc2f3d3-f00f-f1cc-242d-9d6d36e55835.png)

### RadioButton（ラジオボタン）

複数の選択肢の中から1つを選ぶときに使います。
![010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/7dd94012-fbe6-23e7-339e-071afb02702f.png)

## ◇レイアウト用コントロール

### Grid（グリッド）

格子状に領域を区切って配置できます。

サンプルでは列の分割は使っておらず、`RowDefinition`で3行に分割しています。

### StackPanel（スタックパネル）

コントロールを縦並びまたは横並びに配置できます。

### DockPanel（ドックパネル）

コントロールを上、下、左、右、その他に配置できます。

サンプルではテキストボックスを画面サイズに合わせて表示するために使用しています。
![011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/5877e83a-c484-3309-57d9-e5b93546e1d1.png)
![012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/78236efa-e32a-41b9-0f22-21e28e843544.png)

### WrapPanel（ラップパネル）

コントロールを左から右に配置していき、右に入らなかったら折り返して次の行に配置します。

上の黄色背景が横配置のStackPanel、下の青背景がWrapPanelです。
![013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/26bb878d-ce2e-6a59-dfc5-474b4066119e.png)
幅が狭くなった時、StackPanelは見切れてしまいますが、WrapPanelは折り返して表示されます。
![014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/beca89f6-e216-edab-3163-82a3cffd5e0b.png)

## ◇ウィンドウ

Window（フォーム、画面）です。

サンプルではウィンドウのサイズ変更がしやすいようにグリップを表示するよう、
`ResizeMode`プロパティに`CanResizeWithGrip`を設定しています。
![015.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/d70fb64b-eeb9-a7e7-1266-00d7d68830bf.png)

細いウィンドウ縁を掴まなくても、右下の三角でサイズ変更できるようになります。
![016.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/5ee89b11-a11f-1b07-eebf-7ffcefa7c424.png)

## ◇スタイル

複数の同種のコントロールに同じプロパティ設定をする場合、スタイルとして定義して適用すると楽です。
利用するときは、定義したスタイルの名前（`x:Key`）をコントロールの`Style`プロパティに指定してやります。

## ◇コード

```Xml:MainWindow.xaml
<Window x:Class="WpfAppControls.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:WpfAppControls"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" ResizeMode="CanResizeWithGrip">
    <Window.Resources>
        <!-- 入力エリアコンテナのスタイル -->
        <Style x:Key="InputContainer" TargetType="DockPanel">
            <Setter Property="LastChildFill" Value="True"/>
        </Style>
        <!-- 入力エリア見出しのスタイル -->
        <Style x:Key="InputTitleStyle" TargetType="Label">
            <Setter Property="Margin" Value="5,5,5,0"/>
            <Setter Property="Width" Value="60"/>
            <Setter Property="DockPanel.Dock" Value="Left"/>
        </Style>
        <!-- 入力エリア入力部のスタイル -->
        <Style x:Key="InputTextStyle" TargetType="TextBox">
            <Setter Property="Margin" Value="0,5,5,0"/>
            <Setter Property="DockPanel.Dock" Value="Right"/>
        </Style>
        <!-- ラジオボタンの既定スタイル -->
        <Style TargetType="RadioButton">
            <Setter Property="Margin" Value="10"/>
            <Setter Property="Foreground" Value="Blue"/>
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <StackPanel Background="Honeydew">
            <Button Content="Button" Width="100" Click="Button_Click"/>
            <RepeatButton Content="リピートボタン" Width="100" Click="RepeatButton_Click"/>
            <ToggleButton Content="トグルボタン1" Width="100"/>
            <ToggleButton Content="トグルボタン2" Width="100"/>
            <ToggleButton Content="トグルボタン3" Width="100"/>

            <CheckBox Content="チェックボックス" IsChecked="True" Margin="5"/>
            <ComboBox SelectedIndex="0" Width="150" HorizontalAlignment="Left" Margin="5">
                <ComboBoxItem Content="イチゴ"/>
                <ComboBoxItem Content="キウイ"/>
                <ComboBoxItem Content="メロン"/>
            </ComboBox>
            <ListBox SelectedIndex="0" Width="200" Height="55" HorizontalAlignment="Left" Margin="5">
                <ListBoxItem Content="あいうえお"/>
                <ListBoxItem Content="かきくけこ"/>
                <ListBoxItem Content="さしすせそ"/>
                <ListBoxItem Content="たちつてと"/>
            </ListBox>

            <DockPanel Style="{StaticResource InputContainer}">
                <Label Content="名前：" Style="{StaticResource InputTitleStyle}"/>
                <TextBox Text="" Style="{StaticResource InputTextStyle}"/>
            </DockPanel>
            <DockPanel Style="{StaticResource InputContainer}">
                <Label Content="住所："  Style="{StaticResource InputTitleStyle}"/>
                <TextBox Text="" Style="{StaticResource InputTextStyle}"/>
            </DockPanel>
            <DockPanel Style="{StaticResource InputContainer}">
                <Label Content="メモ欄："  Style="{StaticResource InputTitleStyle}"/>
                <TextBox Text="" Style="{StaticResource InputTextStyle}"/>
            </DockPanel>
        </StackPanel>
        
        <StackPanel Orientation="Horizontal" Grid.Row="1" Background="LightYellow">
            <RadioButton GroupName="g1" Content="ラジオボタンA" IsChecked="True"/>
            <RadioButton GroupName="g1" Content="ラジオボタンB"/>
            <RadioButton GroupName="g1" Content="ラジオボタンC"/>
            <RadioButton GroupName="g1" Content="ラジオボタンD"/>
            <RadioButton GroupName="g1" Content="ラジオボタンE"/>
        </StackPanel>
        
        <WrapPanel Grid.Row="2" Background="AliceBlue">
            <RadioButton GroupName="g2" Content="ラジオボタン１"/>
            <RadioButton GroupName="g2" Content="ラジオボタン２" IsChecked="True"/>
            <RadioButton GroupName="g2" Content="ラジオボタン３"/>
            <RadioButton GroupName="g2" Content="ラジオボタン４"/>
            <RadioButton GroupName="g2" Content="ラジオボタン５"/>
        </WrapPanel>
    </Grid>
</Window>
```

```CSharp:MainWindow.xaml.cs
using System.Windows;

#nullable enable

namespace WpfAppControls
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// ボタンクリック時の処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("ボタンが押されました");
        }

        /// <summary>
        /// リピートボタンクリック時の処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RepeatButton_Click(object sender, RoutedEventArgs e)
        {
            // タイトルバーに★を追加
            Title += "★";
        }
    }
}
```

# ■画面作成その2

もう一つプロジェクトを作り、以下のコントロールを使ってみます。

TabControl, Rectangle, Border, Ellipse, Expander, Slider, ProgressBar
![net31gui30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/bbc0ba2a-a502-4bcd-4052-d75ada5ad7c9.png)

![net31gui31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/90fee608-82a7-7f99-d5f6-12d3d893472b.png)

GroupBox, DatePicker, ScrollViewer
![net31gui32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/d04d6b29-90fa-d1be-5266-cd3cea58c3cf.png)

![net31gui33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/e9f0adc1-2f10-34bd-4eb4-ca321d488d92.png)

```Xml:MainWindow.xaml（その2）
<Window x:Class="WpfAppControls2.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:WpfAppControls2"
        mc:Ignorable="d"
        Title="MainWindow" Height="380" Width="600">
    <Grid>
        <TabControl Margin="10">
            <TabItem Header="タブ1" IsSelected="True">
                <StackPanel>
                    <StackPanel Orientation="Horizontal">
                        <Rectangle Width="50" Height="15" Fill="LightBlue" Margin="3"/>
                        <Rectangle Width="50" Height="15" Fill="LightBlue" Margin="3"/>
                        <Rectangle Width="50" Height="15" Fill="LightBlue" Stroke="Black" Margin="3"/>
                    </StackPanel>

                    <StackPanel Orientation="Horizontal">
                        <Border Width="20" Height="20" BorderBrush="Red" BorderThickness="1" Margin="3"/>
                        <Border Width="20" Height="20" Background="Aquamarine" Margin="3"/>
                        <Ellipse Width="50" Height="20" Stroke="Green" Margin="3"/>
                        <Ellipse Width="50" Height="20" Stroke="Yellow" StrokeThickness="3" Fill="DarkGray" Margin="3"/>
                    </StackPanel>

                    <Expander Header="見出し" IsExpanded="True" BorderBrush="LightGray" BorderThickness="2" Margin="5">
                        <StackPanel>
                            <Slider Minimum="0" Maximum="50" Value="10" TickPlacement="Both" Foreground="Red"/>
                            <Slider Minimum="0" Maximum="15" Value="2" TickPlacement="BottomRight" 
                                    Foreground="Blue" Orientation="Vertical" Height="150"/>
                        </StackPanel>
                    </Expander>
                    
                    <ProgressBar Height="15" Width="500" Minimum="0" Maximum="100" Value="33"/>
                </StackPanel>
            </TabItem>
            <TabItem Header="タブ2">
                <StackPanel>
                    <GroupBox Header="GroupBox" Margin="5" Padding="10">
                        <StackPanel Orientation="Horizontal">
                            <RadioButton Content="選択肢1" IsChecked="True" GroupName="grp1" Margin="5"/>
                            <RadioButton Content="選択肢2" GroupName="grp1" Margin="5"/>
                            <RadioButton Content="選択肢3" GroupName="grp1" Margin="5"/>
                        </StackPanel>
                    </GroupBox>
                    
                    <DatePicker Width="120" Margin="5" HorizontalAlignment="Left"/>
                    
                    <ScrollViewer Height="100" Background="LightYellow">
                        <StackPanel>
                            <Button Content="Button1" Width="60" Height="25" Margin="3"/>
                            <Button Content="Button2" Width="60" Height="25" Margin="3"/>
                            <Button Content="Button3" Width="60" Height="25" Margin="3"/>
                            <Button Content="Button4" Width="60" Height="25" Margin="3"/>
                            <Button Content="Button5" Width="60" Height="25" Margin="3"/>
                            <Button Content="Button6" Width="60" Height="25" Margin="3"/>
                        </StackPanel>
                    </ScrollViewer>
                </StackPanel>
            </TabItem>
            <TabItem Header="タブ3" Width="100">
                <StackPanel/>
            </TabItem>
        </TabControl>
    </Grid>
</Window>
```

# ■続き

[.NET Core 3.1 GUIテーマ](https://qiita.com/Kosen-amai/items/a1cb3e83e2749bd00d96)