C# 入門講座
Visual Studio 2019 Visual Studio 2022

第11回 卒業制作

2022/2/27

この記事が対象とする製品・バージョン。環境が2019以前の場合はこの記事の過去の版も参考にしてください。

Visual Studio 2022 Visual Studio 2022 対象です。
VS2019 Visual Studio 2019 対象です。
VS2017 Visual Studio 2017 × 対象外です。過去の版を参照してください。
VS2015 Visual Studio 2015 × 対象外です。過去の版を参照してください。
VS2013 Visual Studio 2013 × 対象外です。過去の版を参照してください。
VS2012 Visual Studio 2012 × 対象外です。過去の版を参照してください。
VS2010 Visual Studio 2010 × 対象外です。過去の版を参照してください。
VS2008 Visual Studio 2008 × 対象外です。過去の版を参照してください。
VS2005 Visual Studio 2005 × 対象外です。過去の版を参照してください。
VS.NET 2003 Visual Studio 2003 × 対象外です。
VS.NET 2002 Visual Studio (2002) × 対象外です。

目次

 

1.目標

入門講座の技術的な解説は前回で終了です。今回は実際に使えるアプリケーションを作っていく過程を紹介します。実際に一緒に試せるように手順は1ステップごとに書いていきますので、是非、みなさんもC#を操作してアプリケーション作りを体感してください。

今回は、この「実際のアプリケーション作りを体感する」ということが目標です。作成するプログラムではいままで解説しなかった知識やキーワードが登場し、多くの人は中身を理解できないかもしれませんが、それでもアプリケーションが完成すれば目標達成です。

私が目指しているのは、新しい発見や、知らなかった操作方法、まだ知らないテクニックにふれることの刺激を感じ取っていただくことです。

このような作業の経験を繰り返すことで実践的な力が身につきます。

今回は Visual Studio 2022 を使った操作を説明します。Visual Studio 2019でもほとんど操作は同じです。それより前のバージョンでは操作方法が異なったり、そもそも説明通りにやってもプログラムが動かないかもしれません。そんなときはこの記事の以前のバージョンを参照してください。以前の記事では古いバージョンのVisual Studioでも通用するやり方を書いています。

 

2.完成品

これから作るアプリケーションは次のようなものです。

■画像1:完成品が動作しているところ。画像は私が最近気に入っているKEY'S CAFEのりんごのタルトです。

主な機能

・画像・動画・テキスト・Html. pdfなどのファイルを見ることができる。

・左側のファイル一覧をクリックすると、そのファイルの内容が右側に表示される。

・ファイル一覧にファイルを追加するには、ファイルをドラッグ&ドロップする。

・ファイル一覧に登録されている内容を保存することができる。保存した内容はあとで呼び出すことができる。

※Excel, WordのファイルはExcel, Wordがインストールされている環境でのみ正常に表示できます。その他のファイルも環境により表示できる場合とできない場合があります。入門講座の練習用プログラムなのでうまく読み込めないファイルがあっても割り切ってください。

 

3.コントロールの配置

3-1.おおまかな進め方

それでは、いよいよ実際にプログラムを始めていきます。完成までの大まかな手順は次のようになります。

1.コントロールの配置。まず見かけだけ完成させます。(「保」「読」ボタンは後回しにします。)

2.ファイル一覧機能。左側のファイル一覧にファイルを追加し、選択したファイルが表示されるようにします。

3.ファイル一覧の保存・読み込み機能。

4.細部と整える。

 

作業する前に一つ注意事項です。Visual Studio 2022の Windows フォーム デザイナーはまだ発展途上です。作業しているとVisual Studioのフォームデザイナーの画面にフォームが表示されなくなることがあります。(将来のバージョンで改善されると期待していますが)

もしフォームが表示されなくなった場合は、次の3つを順に試すと改善されるようです。

  

3-2.プロジェクトの作成

はじめに 新しいプロジェクトを作成してください。

プロジェクトテンプレートは、Windows フォーム アプリ、

プロジェクト名は MultiFileViewer とします。

フレームワークには .NET 6.0 を選択してください。

 

3-3.フォームを広げる

最初、フォームはあまり大きくないかもしれないのでマウスで大きくしましょう。

フォームをクリックすると、右・下・右下に小さな白い四角が表示されます。これをマウスでドラッグするとフォームのサイズを変えられます。

今回は右下の四角をドラッグしてフォームを大きめにしてください。

フォームのサイズは後で変更することもできるので、今後も作業しにくかったらこの方法でフォームの大きさを変更してください。

なお、フォームにいろいろ配置していくとフォームを直接クリックできなくなっていきます。そんなときはフォームのタイトルバー(この画像だと Form1 と表示されている部分)をクリックするのが簡単です。

 

3-4.1つ目のSplitContainerの配置  

SplitContainerコントロール(読み方:SplitContainer = スプリットコンテナ)をフォームに配置します。このSplitContainerコントロールの名前はSplitContainer1となります。

ツールボックス上ではSplitContainerは「Containers」(コンテナ)というグループのところにあります。下の画像も参考にしてください。

■画像:ツールボックス上のSplitContainerコントロール

配置すると自動的にフォーム全体に広がって下の画像のような状態になります。

■画像3:SplitContainerコントロールをフォームに配置したところ

 

3-5.2つ目のSplitContainerの配置

次に、 上の画像でPanel1と書いてある部分にSplitContainerコントロールをもう1つ配置します。このSplitContainerコントロールの名前はSplitContainer2となります。配置すると自動的にPanel1全体に広がって下の画像のような状態になります。

■画像

SplitContainer2の右上に小さな三角が現れるのでクリックします。

三角が現れていない場合は、左側のPanel1とPanel2の間の境界線をクリックすると現れます。

このボタンは、そのコントロールで良く実行する操作をすばやく実行するメニューを表示します。

SplitContainerのタスクから[上下スプリッターの方向]をクリックして下さい。

■画像4:2つ目のSplitContainerコントロールの分割方向を変更する

ここまでの作業でフォームは次のような状態になります。

■画像5:2つ目のSplitContainerコントロールの配置完了

 

 

3-6.ListBoxの配置

ListBoxコントロール(読み方:ListBox = リストボックス)をSplitContainer2Panel2に配置します。名前をlstFileNameにしてください。

■画像6:ツールボックス上のListBoxコントロール

プログラム完成時にはこのListBoxコントロールにファイルの一覧が表示されます。

現段階では次のように表示されているはずです。

■画像7:ListBoxコントロールを配置したところ

配置したらlstFileNameのプロパティを下記のように設定してください。

まとめると設定すべきプロパティは次の通りです。

プロパティ 読み方 設定する値 備考
イベントDock ドック Fill プロパティウィンドウでDockプロパティを選択するときに真ん中にある一番大きな四角が Fill です。
正しく選択すると文字で Fill と表示されます。
イベントAllowDrop アロゥドロップ True lstFileName にファイルをドロップできるようになります。
イベントDisplayMember ディスプレイメンバー Name lstFileName に何を表示するのかを設定します。

  

3-7.WebView2の配置

ファイルの内容を表示する 「WebView2」(ウェブビュートゥー)というコントロールを配置します。(名前に数字が含まれているちょっと変わったコントロールです。)

このコントロールは特殊で、はじめはツールボックスに存在しません。

ツールボックスにこのコントロールを追加するところから作業する必要があります。

 

まず、ソリューションエクスプローラーでMultiFileViewerプロジェクトを右クリックして、[NuGet パッケージの管理」をクリックします。

※右クリックするのはソリューションではなく、その一段下にあるプロジェクトです。

 

NuGetとは、「ニューゲット」と読み、追加のコントロールやライブラリを取得したり管理したりする機能です。これを使うとVisual Studioの標準にはない機能をプロジェクトに取り込むことができます。多数の会社や開発者がNuGetに製品を登録しています。今回のWebView2のように無料で使用できるものもあります。一般的にはこのような機能を「パッケージマネージャー」と呼びます。

NuGetはインターネットにアクセスして検索やコントロールの取得等を行いますので、この機能を使用するにはインターネットに接続している必要があります。

 

NuGetパッケージマネージャーの画面が開いたら、参照をクリックし、検索欄に WebView2 と入力します。

「Microsoft.Web.WebView2」がヒットするので、これをクリックし、右側の「インストール」をクリックします。

「インストール」といっても、Windowsに何かの機能をインストールするわけではありません。今作っているMultiFileViewerプロジェクトにこの機能を組み込むだけです。

確認画面がでるので OK をクリックしてください。インストールは1分くらいで済みます。

 

画面をフォームデザイナーに切り替えて、ツールボックスを確認すると WebView2 が追加されています。

 

この WebView2コントロールをSplitContainer1Panel2に配置してください。

Dockプロパティを Fill にしてください。

そうすると下の画像のように自動的にいっぱいに広がります。

■画像8:WebView2コントロールを配置したところ

WebView2 を貼り付けると名前は WebView21 になります。Buttonを貼り付けると Button1, Button2, … と名前が付くのと同じで WebView2 の 1つ目なのでWebView21 となります。

 

3-8.ここまでの動作確認

この段階で実行してみてください。マウスを使って境界線をドラッグしてフォーム内の区画の大きさが変更できることを確認してください。

左上にPanel1lstFileNameを区切る短い境界線もあるのでこちらも試してみてください。

 

これで基本的な配置作業は終了です。SplitContainerの機能を簡単に補足します。

フォームに配置したSplitContainerコントロールはフォーム上での配置を自動的に調節してくれるコントロールです。 このコントロールには次の2つの働きがあります。

このようにユーザーが自由にサイズを変更できるようにフォームを設計する場合はSplitContainerコントロールがたいへん役に立ちます。

 

4.ファイル一覧機能

4-1.ドロップしたファイルの情報を表示する

この段階では、左側に配置したlstFileNameにファイルをドラッグ&ドロップできるようにします。ドロップしたファイルの情報がlstFileNameに追加されていくようにします。

 

そのために、まず lstFileNameDragEnterイベントハンドラーを生成します。

DragEnterイベントハンドラーを生成するには、プロパティウィンドウでイベントを選択して DragEnter をダブルクリックします。

■画像9:DragEnterイベントの生成

→この辺りの詳しい説明は入門講座第4回 イベントを逃すな をご覧下さい。

 

イベントハンドラーには次のコードを記述してください。

private void lstFileName_DragEnter(object sender, DragEventArgs e)
{
   //ドラッグされているものがファイルであるか確認します。
    if (e.Data!.GetDataPresent(DataFormats.FileDrop))
    {
        //ファイルであればコピー可能であることを宣言します。
        e.Effect = DragDropEffects.Copy;
    }
}

■リスト2:DragEnterイベント

同様にlstFileNameDragDropイベントハンドラーに 次のコードを追加します。

private void lstFileName_DragDrop(object sender, DragEventArgs e)
{
   //ドロップされたファイルのフルパスを取得します。
    string fileName = (e.Data!.GetData(DataFormats.FileDrop) as string[])![0];

    //フルパスからファイル情報を生成してlstFileNameに格納します。
    lstFileName.Items.Add(new System.IO.FileInfo(fileName)); }

■リスト3:DragDropイベント

 

ここまでの作業が完了しているか確認するために、プログラムを実行して、lstFileNameめがけて何か適当なファイルをドラッグ&ドロップしてみてください。ファイルはどのような種類のものでも構いません。たとえば、デスクトップ上の適当なファイルをドロップしてみてください。

ドロップしたファイルのファイル名が次々にlstFileNameに追加されていくようなら正常です。

エラーになる場合は、もう一度コードを見直してください。

エラーにはならないが、正常に動作しない場合はコードを見直すとともにlstFileNameAllowDropプロパティがTrueになっているか、プロパティウィンドウでDragEnterイベントとDragDropイベントの2つにハンドラーが登録されているか確認してください。

 

 

4-2.ファイルの表示

次はいよいよファイル一覧(=lstFileName)でクリックしたファイルが実際に右側の WebView21 に表示されるようにします。

本来ファイルを表示する機能をプログラムするのはとても大変です。ファイルの種類ごとに違った処理が必要となるからです。しかし今回はWebBrowserコントロールがすべてを自動的に処理してくれるので この作業はとても簡単になります。

lstFileNameSelectedIndexChangedイベントに次のコードを追加してください。

private void lstFileName_SelectedIndexChanged(object sender, EventArgs e)
{
    //何が選択されている場合
    if (lstFileName.SelectedItem != null)
    {
        System.IO.FileInfo? file = lstFileName.SelectedItem as System.IO.FileInfo;
        webView21.Source = new Uri(file!.FullName);
        this.Text = Application.ProductName + " - " + file.FullName;
    }
}

■リスト4

これだけで完成です。実行して確かめてみてください。

ファイル一覧(=lstFileName)に画像やhtmlファイルなどをドロップして、ファイル名をクリックするとちゃんとそれが表示されるのが確認できます。

jpg や png などの画像、動画、htmlファイル、PDFファイル、テキストファイル、xmlファイルなどはうまく表示できます。

対応していないファイルはダウンロードの動作が行われます。

 

5.ファイル一覧の保存・読み込み機能

5-1.ボタンの配置

今度は、ファイル一覧の内容を保存する機能、および保存したファイル一覧を呼び出す機能をプログラムします。また、保存・読み込みを実行するためのボタンを配置します。

これにより、一度作成したファイル一覧を2回目以降は簡単に呼び出せるようになります。

 

まずツールバーに見立てて保存ボタンと読み込みボタンを作成します。本当のツールバー機能を実現することも可能なのですが今回はツールバー風にボタンを並べておくだけにします。

次のようにボタンを配置してください。

■画像11:配置後の画面

コントロール 名前 備考
イベントButton(ボタン) btnSave フォームの左上の方に配置してください。
イベントButton(ボタン) btnLoad btnSaveの右横に配置してください。

■表

ボタンの プロパティを下記のように設定してください。

コントロール プロパティ 設定する値
イベントbtnSave イベントText
イベントbtnLoad イベントText

■表

今回は、簡単に漢字で「保」や「読」などと表示するようにしました。かっこよくするためにFontプロパティを設定したり、ここに画像を表示するなど工夫することもできます。絵文字を使うと🗁🗋など簡単にかっこよくできる場合があるのですが保存や読み込みに該当するちょうどよい絵文字がないですね。

 

5-2.ファイル一覧の保存機能

ファイル一覧を保存できるようにするために、btnSaveClickイベントに次のコードを追加してください。

private void btnSave_Click(object sender, EventArgs e)
{
   //▼保存するファイルの指定
   SaveFileDialog dialog = new SaveFileDialog();
    dialog.DefaultExt =".txt"; //既定の拡張子を .txt とします。

    //ファイルを保存するダイアログを開き、閉じられるまで待ちます。OKが押されたか確認します。
    if (dialog.ShowDialog() != DialogResult.OK)
    {
        //OK以外で閉じられた場合何もしません。
        return;
    }

    //▼ファイルへの書き込み
    using (var writer = new System.IO.StreamWriter(dialog.FileName))
    {
        //lstFileNameに格納されているファイル情報を1つずつ取り出します
        foreach (System.IO.FileInfo fileInfo in lstFileName.Items)
        {
            //ファイル情報からフルパスに書き込みます。
            writer.WriteLine(fileInfo.FullName);
        }
    } //end of using
} //end of btnSave_Click

■リスト5

この段階で、このコードがうまく動くかテストしてみてください。正常に動作する場合は、ファイル一覧にいくつかのファイルを追加して、「保」ボタンをクリックすると、ファイル名を選択する画面になります。そこで適当なファイル名を入力し、「保存」をクリックすると、そのファイルにファイル一覧のファイルのフルパスが書き込まれます。

■画像13:ファイル選択画面

プログラムで既定の拡張子として.txtを指定しているため、保存時にファイル名欄で拡張子を指定しないと拡張子は .txt になります。

保存したらメモ帳で保存したファイルを開いてlstFileNameに格納したファイルのフルパスが記録されているか確認してみてください。

 

5-3.ファイル一覧の読み込み機能

今度は、5-2で作成したファイルを読み込めるようにします。btnLoadClickイベントに次のコードを追加してください。

private void btnLoad_Click(object sender, EventArgs e)
{
   //▼開くファイルの指定
    OpenFileDialog dialog = new OpenFileDialog();

    //ファイルを開くダイアログを開き、閉じられるまで待ちます。OKが押されたか確認します。
    if (dialog.ShowDialog() != DialogResult.OK)
    {
        //OK以外で閉じられた場合何もしません。
        return;
    }

    //▼ファイルからの読み込み

    //lstFileNameに格納している内容をすべてクリアします。
    lstFileName.Items.Clear();

    //指定されたファイルの内容を1行ずつ処理します。
    foreach(string line in System.IO.File.ReadAllLines(dialog.FileName))
    {
        //フルパスからファイル情報を生成してlstFileNameに格納します。
        lstFileName.Items.Add(new System.IO.FileInfo(line));
    }
} //end of btnLoad_Click

■リスト6

プログラムができたら、実際に実行して確認してみてください。正常に動作する場合は、「読」ボタンをクリックするとファイルを選択する画面が表示され、そこで選択したファイルの内容を読み込んで、ファイル一覧に表示します。

なお、無関係なファイルを選択するとエラーになったり異常な動作をしますので、かならず「保」ボタンで作成したファイルを選択するようにしてください。

本来は無関係なファイルが指定された場合のチェックをプログラムで行う必要があるのですが、今回は割愛します。というのもこのソフトは仮に異常終了した場合でもユーザーにはほとんどダメージがないからです。

 

6.細部を整える

6-1.実用最小限の製品

ここまでで基本的な機能は完成し、最低限の機能をするアプリケーションはできました。

このように、まず最低限の機能を持つ製品を作って、そこから徐々に機能を追加したり洗練された機能を追加していくというのがソフトウェア開発の基本です。最初のころはやる気にあふれているので欲張っていろいろな機能を付けようとしてしまいがちなのですが、これだととりあえずアプリケーションが使えるようになるまで時間がかかりますし、何か失敗した時にやり直す時間が多くなります。

この考え方で作られた初期のバージョンを「実用最小限の製品」(MVP = Minimum Vialbe Product)と呼びます。

 

今回は、プログラム起動時点でタイトルバーの表示が form1 となっているのが美しくないので直します。それから、対応していないファイルを選択した時にダウンロードの動作が実行されないようにします。また、ファイル一覧にまったくファイルがない状態でも「保」ボタンが押せるのは妙だと思うのでこの場合は「保」ボタンをクリックできないようにします。

他にも目に付く点はあるのですが、それらは簡単に触れるに留め、今回はあまり欲張らないことにしましょう。

 

6-2.タイトルバーの表示

タイトルバーの表示に関しては、すでにlstFileNameSelectedIndexChangedイベントで、アプリケーション名とフルパスが表示されるようにプログラムしてあります。

以下の部分がそのコードです。

this.Text = Application.ProductName + " - " + file.FullName;

これはこれでよいと思うのですが、一番初めにプログラムを開始した時点では「form1」となっているのでこのときにアプリケーション名を表示するように改造します。

FormのLoadイベントに次のコードを追加してください。

private void Form1_Load(object sender, EventArgs e)
{
   this.Text = Application.ProductName;
}

■リスト7

 

 

6-3.ダウンロード機能を無効にする

WebView2コントロールは対応していないファイルを処理させると勝手にダウンロードのような動作をしてしまい邪魔なので、このダウンロード機能を無効にします。

FormのLoadイベントにさらにプログラムを追加して、次のようにしてください。

加えて、Loadイベントハンドラーを定義している行の private と void の間にキーワード async を追加してください。

private async void Form1_Load(object sender, EventArgs e)
{
   this.Text = Application.ProductName; //WebView2のダウンロード機能を無効にします。 await webView21.EnsureCoreWebView2Async(); webView21.CoreWebView2.DownloadStarting += (ds, de) => de.Cancel = true;
}

■リスト

 

6-4.はじめは「保」ボタンをクリックできないようにする

「保」ボタンはファイル一覧が空のときはクリックできないようにしてしまいましょう。

そのために、まずプロパティウィンドウでbtnSaveEnabledプロパティをfalseにしてください。

そして、次の2箇所にコードを追加してください。

1つ目はlstFileNameDragDropイベントハンドラーの一番下です。

private void lstFileName_DragDrop(object sender, DragEventArgs e)
{

   (中略)

    //保ボタンを有効化します。
btnSave.Enabled = true;
}

■リスト8

2つ目はbtnLoadClickイベントハンドラーの一番下です。

private void btnLoad_Click(object sender, EventArgs e)
{
(中略)

    //保ボタンを有効化します。
    btnSave.Enabled = true;

} //end of btnLoad_Click

■リスト9

6-5.他には…?

最後に私が一番気になっているのは見かけです。コントロールをぺたぺた貼っていっただけなので仕方ないのですが、このソフトは見かけが素敵ではありません。

この点の改良は個人のセンスの問題もありますし、技術的な問題もありますが、なんといって「保」ボタンと「読」ボタンがださいです。ここを何とかするにはそれなりに知識が必要となってきますがやはりC#のツールバー機能を利用するとよいでしょう。ツールバーを配置するにはToolStripコントロール(読み方:ToolStrip = トゥールストリップ)を使用しますが始めての方は苦労するでしょう。もうちょっとC#に慣れてきたらチャレンジしてみてください。

それから、ドラッグ&ドロップした後で一覧からファイルを削除したり、並び変えたりなどの操作ができないのは使いにくいですね。

もっと欲張るとファイルを見るだけでなく、何か編集や表示機能を付けるのも良いかもしれません。画像ファイルなら、90度回転させるとか、拡大・縮小するとかです。

7.完成

お疲れ様です。以上でプログラムは完成しました。

多分、実際に作っていただいた方にはほとんどコードを書いてあるままに操作するだけ作業になってしまったのではないかと思いますが、それで良いのです。この作業を通して必ず得るものがあったはずです。冒頭にも書いたように新しい発見や、知らなかった操作方法、まだ知らないテクニックにふれることの刺激、そんなものを感じ取っていただければ私の意図は達成できたことになります。

また、コントロールを貼り付けて、それぞれのイベントにプログラムしていくイベントドリブンという手法についても今回の経験を通して理解が深まったのではないでしょうか。

入門レベルでは、ここからさらに機能を追加していくのはまだ困難だと思います。いつかあなたの考えていることをそのままコードにかけるようになる日が来たら、そのときこそあなたの欲しい機能をどんどんプログラムして行こうではありませんか。現段階ではあせらないで一歩ずつ進んで行きましょう。

 

次の回は、入門講座の最後です。学習した知識が身についているかテストしてみましょう。

C#入門講座 第12回 卒業試験