【C#】WPFアプリケーション入門 #5 配列(多次元配列)

はじめに

前回は繰り返し処理をやりました。今回は配列について扱います。入れておきたいデータが複数ある場合、それぞれのデータを1つのグループにまとめることができます。

お品書き

  1. 配列
  2. 配列とfor 文
  3. 二次元配列
  4. 配列を使ったアプリ

1. 配列

配列は同じ型のデータを複数保管しておきたいときに使います。例えば、フルーツに関するデータを保管しておくとしましょう。

string fruit1 = りんご;
string fruit2 = バナナ;
string fruit3 = ぶどう;
...

と続けていくと確保するデータが肥大するだけでなく、すごく手間がかかります。そしてプログラムが長くなる!
こんなときは配列を使って、同じグループのものを 1 つの変数にまとめてしまえば良いのです。変数は箱という例えでしたが、配列は箱の仕切りだと思ってください。

string[] fruit = new string[] {"りんご", "バナナ", "ぶどう"};

このように宣言します。[] をつけると箱に仕切りができて、fruit の中には { } の中の要素が入っています。new は初期化の意味があり、予めデータを入れておくことができます。
{ }を消すと要素のデータは空っぽの状態で、配列が生成されます。ただし、要素をいくつ保管するかがわからないので、[ ]に要素数を書きます。
この中からデータを取り出すときには次のように書きます。

string[] fruit = new string[] {"りんご", "バナナ", "ぶどう"};
MessageBox.Show(fruit[0]);
MessageBox.Show(fruit[1]);
MessageBox.Show(fruit[2]);

fruitに [ ] をつけ、その中から何番目の要素を取り出すかを指定します。データは 0 番目から始まり、0 にはりんご、1 にはバナナ、2 にはぶどう が入っています。{ } の中に書いた順番に要素に保存されます。これが配列の考え方です。

2. 配列と for 文

上記の内容ではメッセージボックスを 3 回表示する処理になります。が、これだと同じ処理を何度も書くので面倒です。なので for 文を使ってスマートに表現してみます。

string[] fruit = new string[] {"りんご", "バナナ", "ぶどう"};
for (int i = 0; i < 3; i++)
{
    MessageBox.Show (fruit[i]);
}

このようにして要素を i とおけば、更新式で i が加算されるので 0 から順番に表示されます。これで実行してみるとメッセージが3回表示され、それぞれ「りんご」「バナナ」「ぶどう」と表示されます。
ただ、これには問題があります。それは要素数を超えた場合はどうなるかです。i < 3 ならば fruit[0] ~ fruit[2] までの要素で表示されますが、i < 4 にすると fruit[3] を呼び出そうとします。条件式を i < 4 にして実行してみると

f:id:takunology:20190704145201p:plain

エラーが表示されます。「インデックスが配列の境界外です」というのはそのままの意味です。要素が 3 つしかないのに 4 つ目を参照しても「ないんですけど」とエラーを吐かれます。

なので、配列を for 文でぶん回すときは気をつけて実装する必要があります。が、いちいち配列の要素数を数えてプログラムを実装するのも面倒な話です。そこで C# では便利な機能があります。配列の変数名.Length を条件式に組み込めば自動で要素数を取得してくれます。

string[] fruit = new string[] {"りんご", "バナナ", "ぶどう"};
for (int i = 0; i < fruit.Length; i++)
{
    MessageBox.Show (fruit[i]);
}

このようにすると、配列の要素の数だけ繰り返してくれます。という便利な機能の紹介でした。

3. 2次元配列 (多次元配列)

配列は箱に仕切りを入れるようなものと例えました。配列は1次元方向だけでなく、2次元方向にも拡張することが可能です。それどころか3次元、4次元・・・と拡張することができます。2次元以上に拡張した配列を多次元配列といいます。
2次元のイメージは面積だと思います。x 軸方向と y 軸方向をそれぞれ区切って、区画ごとにデータを保管するイメージです。実際にはコンピュータのメモリという部分を扱うのでデータ自体は1次元なのですが、複雑なので別枠で解説したいと思います。2次元配列はこのように宣言します。

int[,] table = new int[3, 3];

型の次に [,] をカンマで区切っています。カンマ1つで2次元配列になります。それを new で初期化しています。[3, 3] では各配列の要素数を指定します。今回は 3,3 なので合計 9 通りの要素を保管できます。
実際に2次元配列で確保した要素数を座標のように表してみます。

private void Button_Click(object sender, RoutedEventArgs e)
{
    int[,] table = new int[3, 3];
    for (int i = 0; i < table.GetLength(0); i++)
    {
        for (int j = 0; j < table.GetLength(1); j++)
        {
            MessageBox.Show(i + "," + j.ToString());
        }
    }
}

これで実行してみると、座標のように表示されます。

f:id:takunology:20190704151551p:plain

さて、今回は Length ではなく GetLength( ) をつかいました。何が違うかというと、後者は取得する要素数を次元で指定できる点が特徴です。今回は2次元配列なので、0と1の次元が生成されています。(コンピュータでは 0 から始まります。) 取得したい次元を指定すればその次元の要素数を取得できるのです。

for 文が二重になって複雑に見えるかもしれませんが、じっくり見ていけば何をしているかわかると思います。外側の for 文は座標で言うところの y 軸 (または行)、内側は x 軸 (または列) を示しています。面積で考えれば左上から右下にかけて順番に要素を読み取っています。

あとは int 型を文字列型にするために ToString() を用いています。

4. 配列を使ったアプリ

多次元配列と繰り返しなどを使って九九表を表示するアプリを作ってみたいと思います。
まずはデザインビューにて次のようなパーツを配置してください。

  • Label 2つ
  • Button 1つ
  • Textbox 3つ

このように配置します。

f:id:takunology:20190704153255p:plain

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="350" Width="600">
    <Grid>
        <Button Content="Button" HorizontalAlignment="Left" Margin="97,150,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
        <Label Content="かける数" HorizontalAlignment="Left" Margin="81,59,0,0" VerticalAlignment="Top"/>
        <Label Content="かけられる数" HorizontalAlignment="Left" Margin="61,90,0,0" VerticalAlignment="Top"/>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="136,62,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" x:Name="kakeru"/>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="136,93,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" x:Name="kakerareru"/>
        <TextBox HorizontalAlignment="Left" Height="200" Margin="301,59,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="239" x:Name="result"/>
    </Grid>
</Window> 

続いてロジックを次のように編集します。

private void Button_Click(object sender, RoutedEventArgs e)
{
    // int.Parse はテキスト(文字列)を数値に変換
    // .Text はテキストボックスに入力された文字を取得
    int x = int.Parse(kakeru.Text);
    int y = int.Parse(kakerareru.Text);

    //テキストボックスで入力された数だけ要素を用意 [x,y]
    int[,] table = new int[x, y];

    //i と j を 1 から始めて積を配列に保管する
    for (int i = 1; i <= table.GetLength(0); i++)
    {
        for (int j = 1; j <= table.GetLength(1); j++)
        {
            //for文で配列要素を指定して積を保管する
            //配列は 0,0 から使用できるので注意!
            table[i - 1, j - 1] = i * j;
        }
    }

    result.Text = "計算結果\n";
    //配列の要素は 0 から始まるので注意!
    for (int i = 0; i < table.GetLength(0); i++)
    {
        for (int j = 0; j < table.GetLength(1); j++)
        {
            // 配列の要素に入っている結果を表示する
            result.Text += table[i, j].ToString();
            result.Text += " "; //空白を開ける
        }
        //一行終わったら改行
        result.Text += "\n";
    }
}

コメントアウトはちょっとした説明を加えています。このプログラムは2次元配列を使わなくてもできるのですが、2次元配列を使うために強引にやってみました。実行してみるとこんな感じになります。

f:id:takunology:20190704155504p:plain

Text += としているのは += に「追記する」という意味があり、=にしてしまうとテキストボックスの中身を初期化してしまいます。試しにやってみてください。最後に代入した文字しか表示されません。

おわりに

ちょっと強引に2次元配列を使ってプログラムを作成してみました。配列を使うと同じグループ属するデータを管理できるので変数をいくつも宣言する必要がなく、楽に実装できます。使い所はプログラムを書いていくにつれてわかると思います。とにかく慣れですね。

え、ポインタですか? C#にポインタ??

【C#】WPFアプリケーション入門 #4 繰り返し処理

はじめに

前回は条件分岐を行いました。今回は繰り返し処理についてです。文字通り、何度も同じような処理をさせたいときに使用します。しかし、アプリでは繰り返し処理をそのまま用いるとよくありません。なぜよくないかは実際に動かして確認してみます。

お品書き

今回やる内容です。

  1. 繰り返し文
  2. 繰り返し文の実装
  3. 非同期処理という解決策

1. 繰り返し文

繰り返し文は様々あります。ここではよく使われる for 文と while文 について紹介します。他にも do-while文 や foreach文 もありますが使うときに解説したいと思います。

1.1 for 文

指定した回数だけ繰り返したいときによく使われます。

for (int i = 0; i < 10; i++)
{
    MessageBox.Show (i.ToString());
}

int i = 0; は初期化を示しています。i < 10 の部分は条件式、 i++ は更新式です。初期化は変数の初期値を用意しておくことで、ここでは 0 に設定されています。条件式は条件に合う限り { } で囲まれた部分の中を処理します。更新式は { } の中の処理が終わるたびに 1 ずつ加算されていきます。

ここで考えるのは条件式についてです。例えば1回目を通過するとき、i = 0で条件式にて比較されます。このとき、0 < 10 なので条件に当てはまります。条件に当てはまるので { } の中を処理します。処理が終わった後は更新式にて i が 1 増えます。そして再び 条件式で比較されます。このときは 1 < 10 なので条件に当てはまり、再び { } 中が処理され・・・を繰り返します。

10回目のとき、i = 10 です。10 < 10 の条件式には当てはまらないので、{ ] の中を処理せずに for 文を抜けます。このようにして繰り返されます。つまり、メッセージボックスでは 0 ~ 9 の数字が表示されることになります。わざわざ MessageBox を 10 回も書く必要がなく、楽できます。

1.2 while 文

条件式に当てはまる限り繰り返す処理です。(永遠に繰り返す事もできます)

int i = 0;
while (i < 10)
{
   MessageBox.Show (i.ToString());
   i++;
}

while の ( ) の中には条件式を書きます。この条件式に当てはまる限り { } で囲まれた処理を繰り返します。もし、(true) にしたらどうなるか想像つくと思います。永遠に繰り返されます(永遠ループして書類送検されr...)。

処理的には for 文と同じです。初期化された変数 i を条件式で比較して更新しています。

1.3 break と continue

break 文はある条件になったときにループから抜け出します。continue 文は条件に合うかぎり、その中の処理を行わずにスキップして、最初から処理させることができます。

int i = 0;
while (i < 10)
{
    if (i == 5)
    {
        break;
    }
    MessageBox.Show (i.ToString);
    i++;
}

このプログラムは i が 5になったら for 文を抜け出します。つまり、メッセージで表示されるのは 0 ~ 4 までです。それ以降の数字は break で抜け出してしまうので表示されません。

for (int = 0; i < 10; i++)
{
    if(i == 4)
    {
         continue;
    }
    MessageBox.Show (i,ToString());
}

このプログラムは i = 4 のとき、continue 以降の処理をスキップして for 文に戻ります。なので、メッセージは 4 だけ表示されません。continue にきたら処理の先頭に戻ると考えていいです。

2. 繰り返し処理の実装

ロジック部分にて繰り返し処理を実装してみます。まずは for 文で 10回メッセージを表示してみます。デザインビューに Button を1つ配置してダブルクリックし、ボタン処理メソッドを作ります。

private void Button_Click(object sender, RoutedEventArgs e)
{
    for (int i = 0; i < 10; i++)
    {
        MessageBox.Show(i.ToString());
    }
}

実行してみると 10 回メッセージが表示されます。10 の部分を他の数に変更すると、その数だけ繰り返されます。

f:id:takunology:20190704122438p:plain

次に while 文で無限にメッセージを表示してみます。

private void Button_Click(object sender, RoutedEventArgs e)
{
    while (true)
    {
        MessageBox.Show("メッセージ");
    }
}

地獄絵図ですね。ウイルスと判断されてもいいくらいです。停止するには Visual Studio の停止マークをクリックするか、タスクマネージャーから終了させます。

そして極めつけはこれです。

private void Button_Click(object sender, RoutedEventArgs e)
{
    int i = 0;
    while (true)
    {
         i++;
         i--;
    }
}

int 型を宣言して足して引いてを繰り返すだけです。

3. 非同期処理という解決策

さて、繰り返し処理をした結果、アプリはどうなったでしょうか。固まったと思います。なぜならば繰り返しをしているからです。繰り返し処理でループしているとユーザの入力を受け付けないので、ユーザは不快でしかありません。なので、繰り返し部分と UI の操作とで処理を分ける必要があります。が、ここで説明するには順番的にアレなのでこの辺で終わります。(理解するには関数やデリゲード、ラムダ式などの知識が必要です。)

おわりに

繰り返し処理させることで同じような処理を簡単に記述することができます。しかし、多用すると操作性が悪くなるのでそのままアプリに使うのは好ましくありません。アルゴリズムメインのコンソールアプリならば大丈夫です。非同期処理もやりたかったのですが、順番的にすっ飛ばしすぎるのでやめました。

初心者に優しいブログでありたい。

参考にどうぞ

github.com

【C#】WPFアプリケーション入門 #3 条件分岐を使う

はじめに

前回までに変数と型をやったので実際に変数同士を比較して、条件分岐していきます。ただ変数同士を比較するだけではアプリとして面白くないので、今回はチェックボックスラジオボタンといったコントロールを扱ってみます。

お品書き

今回やる内容です

  1. 条件分岐
  2. 比較演算子
  3. 条件分岐による場合分け
  4. チェックボックスラジオボタン

1. 条件分岐

文字通り、条件によって処理を変えることです。例えば入力された値が10より大きければ・・・や、入力された値が3ならば・・・というように処理を分岐させていきます。C# で条件分岐を行うときは if や switch などを使います。

1.1 if 文

if 文はあらかじめ場合分けが決まっており、真か偽かで処理を変えます。大抵は2通りで次のように表します。if で囲んだ部分は条件式に合っている場合、else はそれ以外の場合を示します。

if (条件式) 
{
    処理1
}
else 
{
    処理2
}

1.2 switch 文

条件分岐がいくつも分かれている場合です。例えばテレビのチャンネルのように、チャンネルの番号によってそれぞれテレビ局が変わるのと同じです。

switch (変数)
{
    case1:
        処理1 //変数が値1の条件に合うとき、処理1を実行 
        break;

    case2:
        処理2 //変数が値2の条件に合うとき、処理1を実行 
        break;

    //分岐させたいだけ case を用意する

    //上記に当てはまらなかった場合
    default:
        処理 n
        break;
}

2. 比較演算子

変数同士を比較するために使用する記号 (演算子) です。代表的なものを挙げるとこんな感じです。変数 A と B を用意します。

演算子 意味
== 等しい A == B (AとBが等しい)
!= 等しくない A != B (AとBが等しくない)
< より小さい(未満) A < B (AはBより小さい)
> より大きい(超過) A > B (AはBより大きい)
<= 以下 A <= B (AはB以下)
>= 以上 A >= B (AはBより大きい)

! は否定という意味があるので、単に ! を付けると否定の意味になります。この比較演算子と条件分岐をつかうことで、場合分けによる処理が可能となります。

3. 条件分岐による場合分け

では実際に動かしてみます。2つの文字列を認識して、それらが同じ文字列であるかを判定します。
デザインビューに Textbox を2つと Button を1つ配置してください。
Textbox に x:Name をそれぞれ付けます。例として textA と textB という名前を付けました。名前を付けたら Button をダブルクリックしてください。そして、それぞれのテキストから文字列を受け取り、変数に代入して条件分岐で場合分けします。条件によって、メッセージの内容を変えて表示してみます。

private void Button_Click(object sender, RoutedEventArgs e)
{
    string A = textA.Text;
    string B = textB.Text;

    if (A == B)
    {
        MessageBox.Show("同じ文字が入力されています。");
    }
    else
    {
        MessageBox.Show("異なる文字が入力されています。");
    }
}

2つのテキストボックスの文字列が同じであればこのように表示されます。 f:id:takunology:20190702221117p:plain

異なれば、このように表示されます。 f:id:takunology:20190702221128p:plain

次に switch 文を使ってみます。テキストボックス1つだけ使って、特定の文字列を判別させてみます。

private void Button_Click(object sender, RoutedEventArgs e)
{
    string A = textA.Text;

    switch (A)
    {
        case "おはよう":
            MessageBox.Show("おはようございます。");
            break;

        case "こんにちは":
            MessageBox.Show("こんにちは。");
            break;

        case "こんばんは":
            MessageBox.Show("こんばんは。");
            break;

        default:
            MessageBox.Show(A);
            break;
    }
}

これを実行すると、挨拶したときに挨拶してくれるようになります。挨拶以外の内容を入力すると、オウム返しするようになります。試してみてください。

4. チェックボックスラジオボタン

ここまではアプリっぽくないので、チェックボックスラジオボタンを設置して、その値を取得してみたいと思います。取得した値をもとに、条件分岐させてみます。
まずは Checkbox と Radiobutton をデザインビューに配置します。そしてそれぞれに x:Name を追記、表示名を変更してください。自分の場合はこんな感じです。

<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="確定" HorizontalAlignment="Left" Margin="71,118,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
        <CheckBox Content="チェック" HorizontalAlignment="Left" Margin="50,59,0,0" VerticalAlignment="Top" x:Name="checkbox1"/>
        <RadioButton Content="赤" HorizontalAlignment="Left" Margin="141,36,0,0" VerticalAlignment="Top" x:Name="radiobutton1"/>
        <RadioButton Content="青" HorizontalAlignment="Left" Margin="141,56,0,0" VerticalAlignment="Top" x:Name="radiobutton2"/>
        <RadioButton Content="緑" HorizontalAlignment="Left" Margin="141,76,0,0" VerticalAlignment="Top" x:Name="radiobutton3"/>
    </Grid>
</Window>

配置した状態で実行してみるとこんな感じです。

f:id:takunology:20190702225732p:plain

このままでは何もしないので、ロジック側を編集します。

private void Button_Click(object sender, RoutedEventArgs e)
{
    string check;
    string radio;

    if (checkbox1.IsChecked == true)
    {
        //チェックボックスがオンのとき
        check = checkbox1.Content.ToString();
    }
    else
    {
        check = "チェックされてません。";
    }

    if (radiobutton1.IsChecked == true)
    {
        radio = radiobutton1.Content.ToString();
    }
    else if (radiobutton2.IsChecked == true)
    {
        radio = radiobutton2.Content.ToString();
    }
    else if (radiobutton3.IsChecked == true)
    {
        radio = radiobutton3.Content.ToString();
    }
    else
    {
        radio = "選択されていません。";
    }

    MessageBox.Show("チェック:" + check + "\n選択されているもの:" + radio);
}

できたら実行してみます。すると、条件分岐によって各コントロールの表示名が変数に代入されて、それがメッセージとして表示されるようになっています。
f:id:takunology:20190702230903p:plain

IsChecked はチェックされているかどうかの値を取得します。チェックされてるかされてないかなので、True か False が取得できます。

Content は表示名を示しており、これを取得するとコントロール名ごと値を取得できます。が、表示名だけ欲しいので ToString() というものを付けます。

本来、ToString() は型を文字列に変換する意味があります。生のデータは object 型なのでこれを付けないとそのままのデータを受け取ってしまいます。これは結構つかうので、覚えておくといいかもしれません。

else if というのがでてきましたが、if と同じように条件式を用いて比較できます。if だけで分岐させると、1番目の if の条件に当てはまったとしても、2番目、3番目・・・というようにすべてチェックしていくので効率が悪いです。else if ならば、1番目で引っかかれば後はすっ飛ばすので効率が良くなります。

おわりに

さて、条件分岐まで来たので次回は繰り返し処理ですね。 アプリで繰り返し処理するのは良くないのですが、何度も繰り返す必要のあるものを楽に実装できます。なぜ繰り返しが良くないか、次回明らかになります。

参考にどうぞ github.com

【C#】WPFアプリケーション入門 #2 入出力と変数・型

はじめに

前回は出力についてやりました。プログラムを処理していくなかで、何も表示されないと正しく動作しているかが分かりません。加えて、アプリだとユーザ目線になって分かりやすく表現できているかも考慮しなければなりません。出力はもちろん大切なのですが、今回扱う入力も大切なものになります。主にユーザからデータを得るための手段の1つで、アプリを操作することにつながります。

お品書き

今回やる内容はこちらです。プロジェクトは新しく作るか、前回追記したメッセージボックスのコードを消しておいてください。

  1. TextBox を使った入力
  2. 変数と型
  3. Button を使った変数の出力

1. TextBox を使った入力

Visual Studio の上部から "表示" をクリックし、"ツールボックス" を開きます。 f:id:takunology:20190629134950j:plain

左側にツールボックスがでてくるので、"コモンWPFコントロール" から "TextBox" をクリックしながらデザインビューへドラッグアンドドロップします。これでアプリのウィンドウにテキストボックスが配置されました。 f:id:takunology:20190629143918p:plain

同じようにして、Button をデザインビューのどこかに配置してください。 これで実行してみると、テキストボックスに文字を入力したり削除したりできます。ボタンもクリックできます。
f:id:takunology:20190629151218p:plain

ただ、これだけでは何も起こらないので、ロジック側でコーディングしていく必要があります。

2. 変数と型

TextBox に入力した文字をどう扱えばいいか。これを解決するのが変数です。
変数はよく「入れ物」と例えられます。データを保持しておくための箱です。この箱には扱えるデータの種類が決まっており、この種類をといいます。変数を使うためには型を指定する必要があります。

int a = 30; // 整数型
double b = 3.14 // 小数型
string c = "こんにちは" //  文字列型

ここに挙げた例以外にも多くの型がありますが、今はそれほど使いません。気になった人は検索してみてください。変数を宣言するには

型 変数名; → 単に変数を用意しておきたい書き方
型 変数名 = データ; → データを変数に入れておきたい書き方

と記述します。変数名は自由に付けられます。C#では日本語も対応していますが、 プログラムの書き方を統一するためのルール (コーディングスタイル) があるので、あまり日本語は扱われません。

3. 変数の出力

まずは TextBox に入力された文字を受け取り、文字列型の変数に保持しておきたいですね。ただ、このままでは TextBox はロジックで認識されません。なので、XAMLビューにて次のように編集します。TextBox の行にて、最後に追記します。

<TextBox ---省略--- Width="120" x:Name="textbox"/>

x:Name="" はそのコントロールを参照できるようにするおまじないです。" " の中はロジックで使用する際の名前を付けます。これをつけておけばロジックで扱えるということを覚えておきましょう。
次に、デザインビューに配置した Button をダブルクリックしてみてください。すると、ロジック側に

private void Button_Click(object sender, RoutedEventArgs e)
{

}

このようなコードが生成されます。このコードは、ボタンがクリックされたときの処理を示しています。{ } の中は上から順番に処理されます。
この中にテキストボックスからの文字を受け取る変数と、それを出力するためのメッセージボックスを記述していきます。

private void Button_Click(object sender, RoutedEventArgs e)
{
    string moji; // 文字列型を保持するための変数 "moji" を宣言
    moji = textbox.Text;  // テキストボックスの文字を "moji" に代入
    MessageBox.Show(moji); // メッセージボックスで "moji" を表示
}

これで実行してみましょう。テキストボックスの文字を変更してボタンをクリックしてみると、記述した文字がそのまま表示されます。
これで デザイン→XAMLC# という流れで開発していく感覚がつかめたと思います。

おわりに

今回で入出力と変数についての使い方が分かったと思うので、次回は型を変換して計算させてみます。

C#好こ

【C#】WPFアプリケーション入門 #1 文字の出力

はじめに

なぜ今更WPFなのかと思っている人もいるかもしれませんが、自分の学習のためにまた 1 から書いていこうと思います。いろんなサイトで投稿しているうちにバラバラになってしまったので、ここで統一していきます。実は14回分くらいのストック (プログラムを先に作ったもの) があるのですが、小出ししていきます。

お品書き

  1. WPFとは何か
  2. プロジェクトの作成
  3. 文字の表示

1. WPFとは何か

WPF (Windows Presentation Foundation) は、Windows で動くデスクトップアプリのことです。 アプリといえば Windows Store でも入手できますが、これはストアからではなくて直接ダウンロードしてインストールするアプリです。.NET Framework が入っているコンピュータでしか動きません。
Windows Forms というものもありますが、WPFのほうが新しいです。加えてデザイン (UI) とロジック (機能) を分担して開発できるのも特徴です。やってて損はないと思いますが、学習コストが高いという理由で企業からは敬遠されがちです。
余談ですが、デザイン (XAML) とロジック (C#) を分担して作成するアプリは .NET Core や Xamarin , UWP などでも共通です。

2. プロジェクトの作成

Visual Studio を開き、"新しいプロジェクト" をクリックします。そして、"WPFアプリ" を探して次へ進みます。 f:id:takunology:20190627203817p:plain

プロジェクト名は好きな名前を付けて "作成" をクリックします。作成されるとこんな画面が表示されます。 f:id:takunology:20190627204040p:plain

白い画面が、アプリの画面 (デザイン)そのものを表しています。その下に掛かれているコードが XAML という言語で書かれたデザインです。画面上のタブ "MainWindow.xaml.cs" をクリックすると C# 言語で書かれたアプリの機能 (ロジック) 側を制御する画面が表示されます。これら三つの画面を行き来してアプリを仕上げていきます。
画面に呼び方があるのかはわかりませんが、便宜上このブログではそれぞれ

  • デザインビュー
  • XAML ビュー
  • ロジックビュー

と書いていきますので、このような表記があったらそれぞれ対応してください。
じつはこれでアプリは完成しています。F5 キー または画面上部にある "開始" をクリックするとビルドと実行が行われ、アプリが起動します。
デザインや機能を何も記述していないので真っ白なアプリになっています。

3. 文字の表示

文字を表示するにもいくつか種類がありますが、ここでは MessageBox (メッセージボックス) で文字を表示します。メッセージボックスは使用者に確認のメッセージを表示したいときによく使います。今回は練習なので適当な文字を入力してみます。
"MainWindow.xaml.cs" を次のように変更します。

public MainWindow()
{
    InitializeComponent();
    MessageBox.Show("ここに文字を入力");
}

これで実行してみると、このように表示されます。 f:id:takunology:20190628161512p:plain

改行したい場合は、改行するところで \n を文字の中に入れます。

MessageBox.Show("ここに\n文字を入力");

f:id:takunology:20190628161621p:plain

これで文字が出力できます。初歩の初歩ですが、とても大事なことですので覚えておきましょう。

C# を布教したい。

【C#】形態素解析 MeCab を WPFアプリで動かしてみる

1. きっかけ

とある学校の授業で形態素解析をやることになりました。Python で作るようにとのことでしたが、C#が大好きな私はついに手を出してしまいます。「MeCabWPFアプリで作ってみたい」と...。

2. Nugetの導入と実装

MeCab は Nugetにて導入できます。

f:id:takunology:20190625114353p:plain

XAMLはこのように書きました。

<Window x:Class="MeCab.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:MeCab"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Label Content="" HorizontalAlignment="Left" Margin="176,109,0,0" VerticalAlignment="Top" Height="267" Width="450" x:Name="label"/>
        <Button Content="Button" HorizontalAlignment="Left" Margin="356,42,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
        <TextBox HorizontalAlignment="Left" Height="24" Margin="176,80,0,0" TextWrapping="Wrap" Text="ここに何か文字を入力してみます" VerticalAlignment="Top" Width="450" x:Name="textbox" AcceptsReturn="True"/>

    </Grid>
</Window>

ロジック側はこのように書きました。

using NMeCab;
using System.Windows;

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

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            label.Content = "";

            var mecab = MeCabTagger.Create();
            var node = mecab.ParseToNode(textbox.Text);

            while (node != null)
            {
                label.Content += node.Surface + "\n" + node.Feature;
                node = node.Next;
            }
        }
    }
}

3. 実行結果

文字を入力してボタンをクリックしてみますと、ラベルに形態素解析された結果が表示されます。

f:id:takunology:20190625114819p:plain

4. 感想とか

思ったより簡単でした。C# で動かせるのはありがたいことです。
パッケージを作ってくれた人、ありがとう。🙏

参考文献

blog.shibayan.jp