こんにちは、皆さん。今日は簡単な「File Dialog コントロール」を使った、アプリケーションを作成して見ましょう。
前回は、「ColorDialog コントロール」と、「FontDialog コントロール」の使い方を、説明しました。
今回の、「File Dialog コントロール」は、前回以上に最も重要なコントロールで、ファイル関係を扱う場合は、「無くてはならないコントロール」になります。
何よりも、自分でこんな凄いファイル処理を作るのは、プロの方以外では不可能ですし、非常に簡単なコードで、プロ並みの恩恵を受けることができます。
ただ、「File Dialog コントロール」に比べて、実際のアプリが簡単過ぎるというのは、考えないことにしましょう(笑)。
ですからこの機会に、是非習得してみましょう。習得するには、簡単なことを何度も繰り返して、「 空 」で出来るようになりましょう。
ただし、プログラマーの世界では、私個人の意見ですが、「記憶よりも記録です」。ですから、記憶する必要はありません。何処かに、記録して置きましょう(笑)。
何故、記憶しないかというと、コンピューターの世界では、日進月歩が激しいので、古い技術を記憶していても、余り意味がありません。
それよりも、「記録」を比較した方が、良いと思います(飽くまでも、個人的な意見です)。重要なのは、記録した場所を覚えておくことです。これを忘れると、身も蓋もありません(激汗)。
それと、今回は、非常にボリュームがあるので、何回かに分けて、「ゆっくり」と行いましょう。上から順番に行えば、大丈夫です。推理小説のように(笑)。
さぁ、それでは参りましょう。今回は、本格的なアプリケーションになります。結構難しいですよ。Let’s get started !.
FileDialog コントロールとは、何をするのでしょうか?
そうですね、私の経験則で言えば、ファイルを選択する処理としては、古今東西「ピカイチ」の「UI(ユーザーインターフェース)」ですね。
流石、プロ中のプロの本家本元が、提供しているだけのことはあります。
素人の方には、その凄さが分からないと思いますが、非常に高度なコントロールを、非常に高度な使い方で、作成されています。
しかも、使い方が非常に簡単で、たった数行の「C#のソースコード」で、プロの恩恵が受けられるように成っています。m(_ _)m
更に、「Windows 共通」のUIなので、安心して使うことができます。というより、このUIの共通化こそが、実は「Windows の魅力であり本質」なんですね(パワー)。
まぁ、簡単に要約すれば、こんな感じなんですが、是非マスターして見ましょう。
OpenFileDialog コントロール自体は、皆さんもご存知の以下のような「UI」の物です。

先ずは、概要を見てみましょう。
どのような物を作るかを、結果から見てみましょう。通常は、結果は見えませんが、結果から見ると「予習効果」があります。
ただ単に、ソースコードを、打ち込むだけでも十分良いのですが、その前に頭の中で「想像」してみることは、結構面白いですよ。紙と鉛筆は必要ありません。
想像することによって、違いが分かります。違いが分かれば、学習のスコープが明確になるので、ただ漠然と学習するよりも、目標ができるかも知れません。この辺りは、運否天賦です(笑)。
今回作成するアプリケーションは、以下のような物です。FileDialog コントロールを、理解するための構成に成っています。最終的なものではありません。
本来、右ペインにある物は、「MenuStrip コントロール」の中にある物ですが、「その機能」と「使い易さ」を理解するために、このようにしました。
最終的なものは、次回以降に説明します。というより、「MenuStrip コントロール」の中に入れるだけです。
重要なのは、FileDialog コントロールを、使い熟すということです。それには、何回も表示するのが一番です。

【 完成図 】
このアプリケーションを作成します。初心者の方には大変難しそうに見えますが、実はそれ程でもありません。それこそが、RADツールである「C#」の真骨頂なんです。
しかし、アプリケーションを完成させる為には、結構細かい部分まで、確認しなければなりません。何故なら、折角作るのですから、実用で使えるものにしたいですよね(笑)。
ですから、諺でいえば、「百里を行く者は九十を半ばとす」という感じです。
開発名を「FileOpenSave」にしましょう。
開発名は、何でも良いのですが、余り長いとフォルダーの階層も長くなるので、お勧めできません。かと言って、短いと意味が伝わらないので、お勧めできません。
ですから、完全な英語でなくても良いので、意味が伝わるようにしましょう。また、「Top フォルダー名」は、後からでも変更できます。
Visual Studio Community 2022 を起動して、「新しいプロジェクト」を作成する時に、「プロジェクト名」を、「FileOpenSave」にします。Windows 標準のデスクトップ・アプリケーションです。
「プロジェクト名」の解説は、以下の記事に詳しく書いてあります。これが分からないと、プロジェクトが作成できません。既に、分かっている場合は、スキップしてください。

特に重要なのが、以下の二つの記事です。開発前の事柄なんですが、知っているとスムーズに、開発を行う事ができます。こちらも既に、分かっている場合は、スキップしてください。


上記の記事は、完全に、理解しておきましょう。基本的な事なんですが、毎回、同じ内容を書くことも出来ないので。
プロジェクトの最初の画面です。
下(↓)にある画面は、IDE(統合開発環境)を起動して、プロジェクト名を設定した後に、最初に現れる画面(状態)です。ただし、フォーム名を、「Form1.cs」から「OpenSaveForm.cs」に、変更しています。
変更の方法は、上記関連記事の「【C# Form コントロール】先ず、最初に行うこと。」に、詳しく書いてあります。
フォーム名は、上記の方法で、後からでも変更できるのですが、最初に行っておきましょう。
フォーム名というのは、「Form コントロール」が1つしかない場合は、余り意識する必要はないのですが、大きなアプリケーションになると、幾つも「Form コントロール」が必要になります。
その時に、フォーム名を変更する場合は、上記の方法が「一番楽に」変更できます。ですから、この機会に是非マスターしておきましょう。
変更後の最初の画面は、以下の通りです。

ソリューションエクスプローラーで、確認できます。この画面になるまで、試行錯誤してください。簡単なことなんですが、一歩間違うと出来ないかも知れません(笑)。
もし、上手く行かなかった場合は、作成したフォルダーを「削除」してから、一からやり直しましょう。これが、ローカルの良い所です(笑)。
何度も言いますが、ここ迄が一番重要なんです。何故なら、「定義」なので頑張りましょう。
これ以降は、テクニック(定理)なので、色んな言語で共通することもあるでしょう。
フォーム上に、各コントロールを貼って行きます。
それでは、必要なコントロールを、フォーム上に貼って行きます(クリックして、そのままドラッグ&ドロップです)。
先ず、右ペインの下にある「プロパティのタブ」をクリックして、画面中央にある Form をクリックします。これで、Form のプロパティが表示されます。
その時に、何らかのタイミングで、プロパティが表示されない場合がありますが、心配する必要はありません。「ソリューションエクスプローラーのタブ」に戻って、もう一度行いましょう。
先ず、Form のプロパティを設定します。
Form の基本的な状態は、上記の参考記事「【C# Form コントロール】先ず、最初に行うこと。」に、詳しく書いてあります。それを参考にして、以下のプロパティを設定します。
(Name) | OpenSaveForm | 既に成っています |
---|---|---|
AutoScaleMode | None | スケールモード |
Size | 1000, 700 | サイズ |
StartPosition | CenterScreen | 初期位置 |
Font | Yu Gothic UI, 9pt | フォント |
Text | FileOpenSave | テキスト |
ここ迄は、毎回、同じ設定になります。「 Size 」が、異なるくらいです。
これらの設定は、27インチのモニター(1920 × 1080)を使った、「デスクトップ」での設定です。
ノートパソコン等の場合には、大き過ぎる場合もあるので、自分に合った「サイズ」や「フォント」に変更してください。
尚、これ以降の設定もそうですが、飽くまでも基本的なことなので、強制ではありません。自分の好みに設定してみましょう。
次に、StatusStrip コントロールを貼ります。
左ペインの「ツールボックス」から、「StatusStrip」をクリックして、そのままドラッグ&ドロップで「 Form 」の何処かに落とします。自動的に、Form の下のエリアに格納されます。
その状態で、引き続き右ペインの「プロパティ」を設定します。
(Name) | StatusStrip | 名前 |
---|---|---|
Text | StatusStrip | 任意です |
Items | (コレクション) | クリックします |
このコントロールは、結構難しいので単純には説明できません。詳しいことは、「【C# Form コントロール】先ず、最初に行うこと。」に書いてあるので、先に参照してください。m(_ _)m
設定は、主に、「項目コレクション エディタ」で行います。プロパティの「Items: (コレクション)」の三点リーダーをクリックすると、表示されます。
今回、必要なのは、二つの「StatusLabel」です。物にも依りますが、通常は、「2個 ~ 5個」くらいです。
「項目コレクション エディタ」で、「Status Label 追加(A)」を、二回クリックします。其々、以下のプロパティを設定します。
(Name) | MessageStatusLabel | 名前 |
---|---|---|
BorderSides | Right | 境界線の位置 |
Spring | True | 最大化 |
TextAlign | MiddleLeft | テキストの位置 |
Text | 空白 | テキスト |
(Name) | PainStatusLabel | 名前 |
---|---|---|
AutoSize | False | 自動サイズ |
Size | 150, 20 | サイズ |
BorderSides | Right | 境界線の位置 |
Text | ペインを閉じる | テキスト |
このコントロールは、通常、「MenuStrip コントロール」の次に貼ります。そして、「ToolStrip コントロール」は、この後に貼ります。この順番は、必須です。
というのは、「ToolStrip コントロール」は、移動が可能なので「移動できる枠」を、限定する必要があるからです。まぁ、非常に高度なテクニックなので、通常は使いません。
そうですね、「MenuStrip コントロール」、「StatusStrip コントロール」、「ToolStrip コントロール」を使い熟せるようになると、立派なアプリケーションが、作成できます(ナイス)。
基本的に、ここ迄が、「ベースに成る Form コントロール」の設定です。ですから、毎回同じ設定になるので、「テンプレート」や「スケルトン」にして置くと、効率が上がります。
今回メインの、Dialog コントロールを貼ります。
今回は、ファイル関係の処理を行うアプリケーションなので、「OpenFileDialog コントロール」と、「SaveFileDialog コントロール」を使います。
これらのコントロールは、通常、単独のファイル(テキストファイルや、画像ファイル)を扱うアプリケーションの場合には、必須になります。
例えば、当サイトでは扱わないのですが、大きなシステムを構築する場合は、「メニューシステム」のような大きな階層構造になっていたりするので、当サイトとは、全く作り方が異なります。
この場合は、「ヒエラルキー」のような構成なので、単独のファイルを扱うという事はないと思います。画面構成も、根本的に異なってきます。
当サイトで扱うアプリケーションは、本当に小さなアプリケーションで、世に出すことは出来ないのですが、自分の仕事や趣味に、ちょっと役に立てれば良いかな?という代物です(笑)。
OpenFileDialog コントロールを貼ります。
「ツールボックス」から、「OpenFileDialog」をクリックして、Form の何処かに落とします。自動的に、Form の下のエリアに格納されます。
そのまま引き続き右ペインの「プロパティ」を設定します。
(Name) | OpenFileDialog | 名前 |
---|
驚くかも知れませんが、これだけです。というのは、どのようなファイルを扱うかというのは、デザイン時には分からないので、ソースコードの方で適選に設定します。
勿論、既に分かっている場合には、其々設定してください。それと、ディフォルトの設定は、充分使い易くなっています。
SaveFileDialog コントロールを貼ります。
「ツールボックス」から、「SaveFileDialog」をクリックして、Form の何処かに落とします。自動的に、Form の下のエリアに格納されます。
そのまま引き続き右ペインの「プロパティ」を設定します。
(Name) | SaveFileDialog | 名前 |
---|
こちらも、「OpenFileDialog コントロール」と同じ理由で、これだけです。
SplitContainer コントロールを貼ります。
このコントロールは、当サイトでは、非常に重要なコントロールになります。というのは、画面を必要に応じて、幾つにも分割できるからです。
ただし、幾つにも分割できるからといっても、私の経験則では、三つまでが使い易いと思います。
以前は、「Splitter コントロール」が使われていたのですが、今は、「SplitContainer コントロール」が推奨されています。
ただし、「SplitContainer コントロール」では、画面を細かく分割することは難しいので、その場合は、「Splitter コントロール」でも良いかも知れません(激汗)。
SplitContainer コントロールは、結構大きなコントロールで、初期状態で「Panel1」と「Panel2」の領域を保有しています。それぞれ独自に設定します。
ですから、色々な装飾を行うには、「本体」、「Panel1」、「Panel2」の、三つの領域のプロパティを設定する必要があります。今回は、普通の装飾になります。
先ずは、本体を貼ります。
「ツールボックス」から、「SplitContainer」をクリックして、Form上 に貼ります。そして、そのまま引き続き右ペインの「プロパティ」を設定します。
Name | SplitContainer | 名前 |
---|---|---|
Dock | Fill | 結合方法 |
FixedPanel | Panel2 | 固定パネル |
SplitterDistance | 676 | 分割線の位置 |
SplitterWidth | 8 | 分割線の幅 |
BorderStyle | FixedSingle | 境界線の種類 |
Cursor | SizeWE | マウスのイメージ |
Panel1 を設定します。
そのままの状態で、SplitContainer コントロールの、「分割線」より左側の領域の、「真ん中辺り」をクリックします。ここは、「Panel1」の領域です。
そして、そのまま引き続き右ペインの「プロパティ」を設定します。
Cursor | Default | マウスのイメージ |
---|
今回は、シンプルにこれだけです(笑)。通常の「Panel」と何も変わりません。
Panel2 を設定します。
更に、そのままの状態で、SplitContainer コントロールの、「分割線」より右側の領域の、「真ん中辺り」をクリックします。ここは、「Panel2」の領域です。
そして、そのまま引き続き右ペインの「プロパティ」を設定します。
Cursor | Default | マウスのイメージ |
---|
こちらも、これだけです。尚、「Panel2」は、基本的に「コマンド類」を入れる領域です。
私は右利きなので、右側に「コマンド類」を設定しているのですが、左利きの場合は、「Panel1」と「Panel2」を、入れ替えれば良いです。
後は、必要に応じて、「Panel1」と「Panel2」を入れ替えて、設定すれば良いです。
必要なコントロールを貼って行きます。
それでは、アプリケーションに必要なコントロールを、「Panel1」と「Panel2」に貼っていきます。
Panel1 に、TextBox を貼ります。
「Panel1」には、ファイルの内容を表示したり、編集して保存する「TextBox」を貼ります。
「ツールボックス」から、「TextBox」をクリックして、Form上 の「Panel1」に貼ります。そして、そのまま引き続き右ペインの「プロパティ」を設定します。
(Name) | MainTextBox | 名前 |
---|---|---|
HideSelection | False | 選択の非表示 |
MaxLength | 0 | 最大文字数 |
Multiline | True | 複数行の有無 |
Dock | Fill | 結合方法 |
BorderStyle | None | 境界線の種類 |
Font | 游ゴシック, 12pt | フォント |
ScrollBars | Both | スクロールバー |
基本的に「TextBox」は、Windows 付属の「メモ帳」と、同等の機能を持っています。多少の機能制限はあるものの、軽量で非常に使い易いコントロールです。
Panel2 に、コマンド類を貼って行きます。
これから Form 上の「Panel2」に、色んなコントロールを貼って行くのですが、必ずしもその設定通りになるとは、限りません。
ですから、多少の誤差はあると思いますが、余り気にしなくても構いません。自分の環境に、最も適切な値に「再設定」して下さい。例えば、ノートパソコンとかの場合は。
以下の値は、飽くまでも、デスクトップ(1920 × 1080)としての基本的な値です。幾らでも、変更は可能です(Location や Size 等)。
「ツールボックス」から、「Button」をクリックして、Form 上の「Panel2」に貼ります。そして、そのまま引き続き右ペインの「プロパティ」を設定します。
(Name) | ClearButton | 名前 |
---|---|---|
Location | 70, 30 | 位置 |
Size | 160, 40 | サイズ |
Text | クリア | テキスト |
これは、「MainTextBox」のテキストを、クリア(初期状態)する為のものです。
次に、「Button」をクリックして、Form 上の「Panel2」に貼ります。引き続き「プロパティ」を設定します。
(Name) | FileOpenButton | 名前 |
---|---|---|
Location | 70, 100 | 位置 |
Size | 160, 40 | サイズ |
Text | ファイルを開く | テキスト |
この「Button」は、「OpenFileDialog コントロール」を、表示する為のものです。ファイル自体は、「OpenFileDialog コントロール」で選択します。
次に、「Label」をクリックして、Form 上の「Panel2」に貼ります。引き続き「プロパティ」を設定します。
(Name) | DirtyLabel | 名前 |
---|---|---|
Enabled | False | 稼働の有無 |
AutoSize | False | サイズの自動化 |
Location | 70, 170 | 位置 |
Size | 160, 40 | サイズ |
BorderStyle | FixedSingle | 境界線の種類 |
ForeColor | Red | 前景色 |
Text | 変更されました | テキスト |
TextAlign | MiddleCenter | テキストの位置 |
このラベルは、「テキストが変更されたかどうか」を、表示するためのラベルです。この手の「フラグ」は通常は、「表」に出て来ないものですが、練習用なので表示してみました。
次に、「Button」をクリックして、Form 上の「Panel2」に貼ります。引き続き「プロパティ」を設定します。
(Name) | FileSaveButton | 名前 |
---|---|---|
Location | 70, 240 | 位置 |
Size | 160, 40 | サイズ |
Text | 名前を付けて保存 | テキスト |
この「Button」も、「SaveFileDialog コントロール」を、表示する為のものです。ファイル自体は、「SaveFileDialog コントロール」で選択します。
次に、「TextBox」をクリックして、Form 上の「Panel2」に貼ります。引き続き「プロパティ」を設定します。
(Name) | SearchTextBox | 名前 |
---|---|---|
WordWrap | False | 折り返しの有無 |
Location | 50, 320 | 位置 |
Size | 200, 27 | サイズ |
検索したい「文字列」を、入力するエリアです。
次に、「CheckBox」をクリックして、Form 上の「Panel2」に貼ります。引き続き「プロパティ」を設定します。
(Name) | UpLowLetterCheckBox | 名前 |
---|---|---|
Location | 52, 370 | 位置 |
Size | 196, 24 | サイズ |
Text | 大文字と小文字を区別する | テキスト |
検索時に、大文字と小文字を、区別するかどうかを選択します。
次に、「Button」をクリックして、Form 上の「Panel2」に貼ります。引き続き「プロパティ」を設定します。
(Name) | SearchButton | 名前 |
---|---|---|
Location | 70, 420 | 位置 |
Size | 160, 40 | サイズ |
Text | 文字列の検索 | テキスト |
文字列を検索して、「強調表示」します。一度のクリックで、一回検索します。文章の最後まで到達すると、自動的に「ラップアラウンド」します。
次に、「CheckBox」をクリックして、Form 上の「Panel2」に貼ります。引き続き「プロパティ」を設定します。
(Name) | WordWrapCheckBox | 名前 |
---|---|---|
Location | 87, 500 | 位置 |
Size | 125, 24 | サイズ |
Checked | True | チェックの有無 |
ForeColor | Green | 前景色 |
Text | 右端で折り返す | テキスト |
テキストの「WordWrap」を変更します。
以上で、デザインは終了なんですが、更に「既定のイベント」を、このデザイナーから「ソースコード」に追加する必要があります。
まぁしかし、一息入れましょう。コーヒーブレイクです。

起きて半畳寝て一畳、天下取っても二合半。
こういう諺とか、名言というのは、学校ではなく「漫画」とか「小説」とか「映画・ドラマ」で知ることが、多いですね。
この後は、イベントを追加して、その中にソースコードを入れれば、アプリケーションが完成します。
先ずは、プロパティを設定しましょう。
というのは、「イベント」を設定したいのですが、プロパティが無いと、コード支援の「インテリセンス」が適切に働かないので、イベントの中身のソースコードを、上手く設定できません。
まぁ慣れて来ると、その辺りは幾らでも対応出来るのですが、最初の間は混乱すると思うので。
先ず、全体の構成は、以下のようになります。

この中の、「● プロパティ」の部分を設定します。この折り畳みは、「#region ~ #endregion」で構成されています。
尚、その上の「三点リーダー」は、エディターの折り畳みです。左側の「>」をクリックすると、展開されます。
私は、見た目が分かり易いように、「● XXXXX」という文言にしているのですが、通常は「XXXXX」だけの方が標準だと思います(世界的に)。
「#region ~ #endregion」に関しては、以下の記事に詳しく書いてあります。

● プロパティを設定します。
それでは、以下のソースコードを、コメントも含めて全て入力してください。出来るだけ、手入力で入力すると、愛着が湧きます(笑)。
#region ● プロパティ
private string _fileName = string.Empty;
/// <summary>
/// ファイル名を取得または設定します。
/// </summary>
/// <remarks>MainTextBox に表示するテキストファイル。</remarks>
private string FileName
{
get { return _fileName; }
set
{
_fileName = value;
this.Text = Path.GetFileName(_fileName) + " - FileOpenSave";
}
}
private bool _isDirty;
/// <summary>
/// テキストが変更されたかどうかを取得または設定します。
/// </summary>
private bool IsDirty
{
get { return _isDirty; }
set
{
_isDirty = value;
// テキストの変更状態を設定します。
DirtyLabel.Enabled = _isDirty;
}
}
/// <summary>
/// 現在の検索位置を取得または設定します。
/// </summary>
private int SearchCurrentIndex { get; set; } = 0;
#endregion
コメントも含めて、全て再現してください。分からない部分があると、別途コメントして置きましょう。日付とか入れて置くとより丁寧ですが、中々出来ません(笑)。
「///」の使い方は、過去の記事に詳しく書いてあるので、参照してください。
ここで、重要なのは、「自動プロパティ」と「手動プロパティ」の違いです。
「自動プロパティ」というのは、{ get; set; } だけの場合に成立します。「手動プロパティ」というのは、{ get; set; }の中に、コードを入れる場合に行う手続きです。
形式は、色々な方法があるのですが、上記の方法は一例に過ぎません。
「手動プロパティ」というのは、先ず、プロパティと同じ名前で、先頭を「_小文字」にしたローカル変数を、何処かに儲けます。
このローカル変数が、プロパティの中身になります。このローカル変数に、全ての値が入ります。そして、プロパティ自体は、このローカル変数を「安全に保護」します。
これが、「プロパティ」の凄いところなんです。つまり、プロパティ自体は、変数ではなく「関数」です。ですから、プロパティ自体に、値を入力することは出来ません。
要は、値を入出力する方法を、提供していることになります。これによって、値の安全性が確保できる分けです。
尚、「● 初期設定」の部分は、コード支援に影響しないので、一番最後に設定します。
それでは、本命のイベントを設定しましょう。
結構、「茨の道」なので、覚悟して行いましょう(笑)。先ずは、お茶を飲んでから。
今回、使用する「イベント」は、殆どが各コントロールの「ディフォルトのイベント」です。
ですから、デザイン上で「各コントロール」を、ダブルクリックするだけで、自動的にソースコード上にイベント用のコードが、作成されます。
ただし、むき出しの「イベントコード」なので、見栄えを良くしたり、コメントを付けたり、「#region ~ #endregion」で囲ったりするのは、自分でしなければなりません。
基本的に、ソースコードは、「そこにある文字列」を判断します(文字ベース)。ですから、文字列が重複しない限り、どこに存在してもエラーにはなりません。
それでは、一つ一つゆっくりと、イベントを作成して行きましょう。
テキストをクリアします。
IDE のデザイン上で、上記「完成図」の右ペインにある「クリア」ボタンを、ダブルクリックします。
これでソースコード上に、「クリア」ボタンの「Click イベント」が作成されたので、一旦「ソースコードのタブ」をクリックして、「コード」を完成させます。
以下のソースコードを、コメントも含めて、全て打ち込んでください。
「/// XML コメント」の方法は、関連記事の「【C# Form ソースコード】先ず、コードで便利な機能。」に、詳しく書いてあります。
/// <summary>
/// テキストをクリアします。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ClearButton_Click(object sender, EventArgs e)
{
// テキストをクリアするかどうかを確認します。単純化して確認は、
// 一回にしています。通常は、テキストの保存処理が入ります。
DialogResult ret = MessageBox.Show(
"テキストの内容をクリアしても良いですか?", "FileOpenSave",
MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
// テキストをクリアします。
if (ret == DialogResult.OK)
{
MainTextBox.Text = "";
IsDirty = false;
MessageStatusLabel.Text = "テキストをクリアしました。";
}
MainTextBox.Focus();
}
この動作(イベント)は、「MainTextBox」のテキストをクリアして、初期状態にします。
テキストファイルを開きます。
次のイベントを作成するために、再び「IDE のデザイン」に戻ります。尚、全ての「イベントコード」を作成するまで、この操作の繰り返しです。
IDE のデザイン上で、「ファイルを開く」ボタンを、ダブルクリックします。
本来なら、これだけなんですが、テキストファイルを選択する為に、「OpenFileDialog コントロール」を使用する為、「FileOk イベント」を作成しなければなりません。
ですから、そのまま下段にある「OpenFileDialog」を、ダブルクリックしてください。
次に、ソースコードに行って、以下のコードを全て打ち込みます。
/// <summary>
/// ファイルを開きます。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FileOpenButton_Click(object sender, EventArgs e)
{
// テキストの保存を確認します。こちらも単純化しています。
if (IsDirty)
{
DialogResult ret = MessageBox.Show(
"テキストが変更されているので、「 保存 」または「 クリア 」"
+ "してください。", "FileOpenSave",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
else
{
// 開くファイルを選択します。
OpenFileDialog.FileName = "";
OpenFileDialog.ShowDialog();
// 「通常」この後の処理は、OpenFileDialog.FileOK イベントの方で
// 行いますが、場合によっては、そのイベントを使わずに、直接呼び出す
// 事もあります。例えば、以下のように。
//
// DialogResult dialog = OpenFileDialog.ShowDialog();
//
// if (dialog == DialogResult.OK)
// {
// OpenFileDialog_FileOk(null, null);
// }
}
MainTextBox.Focus();
}
/// <summary>
/// 選択されたファイルを開きます。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OpenFileDialog_FileOk(object sender, CancelEventArgs e)
{
try
{
// テキストファイルを開きます。
// 今回は、ReadToEnd() なので、content を使わずに、直接
// MainTextBox.Text に代入しても構いません。
string content = "";
using (StreamReader sr = new StreamReader(
OpenFileDialog.FileName, Encoding.UTF8))
{
content = sr.ReadToEnd();
}
MainTextBox.Text = content;
MainTextBox.SelectionStart = 0;
// 関連処理を行います。
FileName = OpenFileDialog.FileName;
IsDirty = false;
MessageStatusLabel.Text = "ファイルを開きました。";
}
catch (Exception ex)
{
// 定番のエラー処理です。
MessageBox.Show("Error: Could not read file to disk. \r\n"
+ "Original error: " + ex.Message);
}
}
この二つのイベントによって、テキストファイルを選択して、「MainTextBox」にその内容を表示することになります。
ただし、この一連の作業は、初心者の方には、全く分からないと思います。どのタイミングで、「FileOk イベント」に移行して来るのか?、が。
それは、コードの「OpenFileDialog.ShowDialog();」で、「OpenFileDialog コントロール」が表示されます。そして、ファイルを選択した後に、「FileOk イベント」に移行します。
更に、「FileOk イベント」が終了すると、再び、「OpenFileDialog.ShowDialog();」の次の行に戻って来ます。
このように、イベントのタイミングというのは、数も沢山あるし「その順番」も、微妙に影響してきます。ですから、何度も失敗して、慣れるしかありません。頑張りましょう。
それと、ここで重要なのは、テキストファイルを読み込む時に、「文字エンコーディング」を指定していることです。今回は、「Encoding.UTF8」にしていますが、他にも色々あります。
上記「コード」上の、「StreamReader」か「Encoding」上をクリックしてから、「F1」を押下すると、詳しい説明のヘルプが表示されます。
尚、「日本語 (SHIFT-JIS)」の場合は、「UTF-8」等とは違って、「GetEncoding(“shift_jis”)」を使います。 これは、「保存」の時も、同じ理屈です。
また何時か、アプリケーションを作成して、説明したいと思います。
テキストが変更されました。
本来、この手の「フラグ(状況)」は、内部情報なので表示しないのですが、その仕組みを理解するために、敢えて表示してみました。
この場合は、少し複雑で、「変更されました」ラベルは、入力ではなく出力だけなので、後で、出力に関するイベントで使います(一番最後に、少しハイレベルな事をします)。
しかし今は、取り合えず普通に、「IDE のデザイン」に戻って、左ペインにある「MainTextBox」を、ダブルクリックします(何処でも良いのですが、中央辺り)。
次に、ソースコードに行って、以下のコードを全て打ち込みます。
/// <summary>
/// テキストが変更されました。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainTextBox_TextChanged(object sender, EventArgs e)
{
IsDirty = true;
}
これは、何でもかんでも、「MainTextBox」に変化がある場合に、行う処理です。「TextBox」を扱う場合は、定番中の定番です。
テキストファイルを名前を付けて保存します。
本来は、単純に「保存」だけでも良いのですが、大切なファイルを、「服の袖で更新」してしまうと大変なので、ワンクッション置きました(笑)。
飽くまでも自分用なので、後々色々と工夫してください。最終的には、この手の処理は、「MenuStrip コントロール」の中に入れます(Windows 共通)。
それでは、「IDE のデザイン」に戻って、「名前を付けて保存」ボタンを、ダブルクリックします。
ソースコードに行って、以下のコードを全て打ち込みます。
/// <summary>
/// 名前を付けて保存します。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FileSaveButton_Click(object sender, EventArgs e)
{
// 保存するファイルを選択します。
SaveFileDialog.FileName = Path.GetFileName(_fileName);
// FilterIndex は、色々な方法があるので、正解はありません。
SaveFileDialog.FilterIndex = OpenFileDialog.FilterIndex;
if (SaveFileDialog.ShowDialog() == DialogResult.OK &&
SaveFileDialog.FileName.Length > 0)
{
try
{
// テキストを保存します。
using (StreamWriter sw = new StreamWriter(
SaveFileDialog.FileName))
{
sw.Write(MainTextBox.Text);
}
// 関連処理を行います。
FileName = SaveFileDialog.FileName;
IsDirty = false;
MessageStatusLabel.Text = "名前を付けて保存しました。";
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not save file to disk. \r\n"
+ "Original error: " + ex.Message);
}
}
MainTextBox.Focus();
}
これは、「MainTextBox」の内容を、「名前を付けて」ファイルに保存します。
実は、こちらも処理も、「SaveFileDialog」に「FileOk イベント」があるので、「OpenFileDialog」のように「FileOk イベント」を、作成してもよいのですが、
公式のマニュアルでも、端折っているので、それに習いました(笑)。
しかし実は、この手のファイル処理は、「FileOk イベント」を使わない方が、何かと良いかも知れません(経験的に)。
文字列を検索します。
この間に、「SearchTextBox」と「UpLowLetterCheckBox」があるのですが、これらは単に情報だけなので、イベントは有りません。
「IDE のデザイン」に戻って、「文字列の検索」ボタンを、ダブルクリックします。
ソースコードに行って、以下のコードを全て打ち込みます。
/// <summary>
/// 文字列を検索します。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SearchButton_Click(object sender, EventArgs e)
{
StringComparison comparison = UpLowLetterCheckBox.Checked ?
StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
// 現在のキャレットの位置から、文字列を検索します。
SearchCurrentIndex = MainTextBox.SelectionStart
+ MainTextBox.SelectionLength;
int newIndex = MainTextBox.Text.IndexOf(
SearchTextBox.Text, SearchCurrentIndex, comparison);
// 終端まで達した場合は、最初からもう一度検索します。
if (SearchCurrentIndex > 0 && newIndex < 0)
{
newIndex = MainTextBox.Text.IndexOf(
SearchTextBox.Text, 0, comparison);
}
if (newIndex >= 0)
{
// 検索結果を強調します。
MainTextBox.SelectionStart = newIndex;
MainTextBox.SelectionLength = SearchTextBox.Text.Length;
MainTextBox.ScrollToCaret();
MessageStatusLabel.Text = "文字列を検索しました。";
}
else
{
// 見付からなかった場合。
MessageBox.Show("\"" + SearchTextBox.Text + "\""
+ " が見つかりません。", "FileOpenSave",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
MainTextBox.Focus();
}
こちらは、「メモ帳」にある、「検索」を再現してみました。色んなオプションを付けると、多彩な検索が出来るようになります。
テキストを右端で折り返します。
「IDE のデザイン」に戻って、「右端で折り返す」チェックボックスを、ダブルクリックします。
ソースコードに行って、以下のコードを全て打ち込みます。
/// <summary>
/// テキストの折り返しを変更します。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void WordWrapCheckBox_CheckedChanged(object sender, EventArgs e)
{
// WordWrap を変更します。
MainTextBox.WordWrap = WordWrapCheckBox.Checked;
MainTextBox.ScrollToCaret();
MainTextBox.Focus();
// 関連処理を行います。
MessageStatusLabel.Text = "折り返しを変更しました。";
}
これは、「MainTextBox」の「WordWrap」を変更します。この時に、キャレットの位置を確保しています。
基本的なイベントは、以上で終了です。
最後に、初期設定を行いましょう。
これが無いと、上手く行きません。通常、「初期設定」は、文言とは逆に最後に設定するのが、定番です(笑)。
それでは、以下のコードを設定してください。「コンストラクター」内と、「● 初期設定」の二つです。
/// <summary>
/// 新しいインスタンスを作成します。
/// </summary>
public OpenSaveForm()
{
// デザイナーが行う初期設定です。
InitializeComponent();
// 個人的な初期設定を行います。
InitializeMyMember();
}
#region ● 初期設定
/// <summary>
/// 初期設定を行います。
/// </summary>
private void InitializeMyMember()
{
// OpenFileDialog を設定します。
OpenFileDialog.Filter =
"txt csv files (*.txt; *.csv)|*.txt; *.csv|" +
"html css files (*.html; *.css)|*.html; *.css|" +
"All files (*.*)|*.*";
OpenFileDialog.FilterIndex = 1;
OpenFileDialog.RestoreDirectory = true;
// SaveFileDialog を設定します。
SaveFileDialog.Filter = OpenFileDialog.Filter;
SaveFileDialog.FilterIndex = OpenFileDialog.FilterIndex;
// 最初のご挨拶。
MessageStatusLabel.Text = "FileDialog コントロールを習得しましょう。";
}
#endregion
これで、一応基本的なことは、終了です。後は、もう少しです。頑張りましょう。
それでは、この状態で動かしてみましょう。
上手く出来たら、「▲ 開始」か「F5」を押下しましょう。中々、一回で上手く行くことは、無いと思いますが、エラーの場合は、丁寧な「エラー一覧」が出ますので、修正しましょう。
まぁ、これだけの量のコードを、手入力で入力するのですから、私でも一回では無理だと思います(笑)。
兎に角、色々と動かしましょう。動かすことによって、「プログラムとイベントの関係」が、理解できるようになります。
そして、テキストファイルを、表示しましょう(小さい物から、大きい物まで)。それから、検索しましょう。「検索」と言うのは、テキストファイルで、最も必要な処理ですから。
今回、テキストファイルの表示用として、「TextBox」コントロールを使っていますが、動かすことによって、「TextBox」の凄さが、分かると思います。
「TextBox」用のプログラムは、一行も書いていませんが、こんな凄い機能が予め実装されています。これが、「RAD ツール」なんです。
それともう一つ、確認して欲しいのが、「MainTextBox」に文字を打ち込んだ時に、右ペインの「変更されました」というラベルが、どのように「変化」したかを見てください。
「黒い枠の中に、赤い文字」が表示される筈です。これを、「クリア」ボタンと併用して、何回も繰り返しましょう。
最後に、特別なイベントを設定します。
最後に、二つのイベントを設定します。これは、標準の動作ではなく、個別の動作になります。まぁ所謂、カスタマイズというものです(笑)。
一つは、右ペインが「開閉」出来るようにしましょう。基本的に、右ペインにある物は、テキストファイルの編集時には、余り必要無い物なので、隠せるようにします。
もう一つは、「変更されました」ラベルの黒い枠を、赤い枠に変えましょう。これは、通常のプロパティの設定だけでは出来ません。
右ペインの「開閉」を行います。
「IDE のデザイン」に戻って、StatusStrip の「ペインを閉じる」ラベルを、ダブルクリックします。
ソースコードに行って、以下のコードを全て打ち込みます。
/// <summary>
/// 右ペインを閉じたり開いたりします。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>ステータスラベルは、色々と活用出来ます。</remarks>
private void PainStatusLabel_Click(object sender, EventArgs e)
{
if (SplitContainer.Panel2Collapsed == false)
{
SplitContainer.Panel2Collapsed = true;
PainStatusLabel.Text = "ペインを開く";
}
else
{
SplitContainer.Panel2Collapsed = false;
PainStatusLabel.Text = "ペインを閉じる";
}
}
これが、「SplitContainer コントロール」の、使い易いところなんです。
ただし、「SplitContainer」コントロールには、「Panel2」を固定にすると、何らかの拍子に「幅が狭くなる」という状態が発生します。
本来なら、「Visual Studio Community」のバージョンアップで、修正してもらうのが一番良いのですが、「C# のコード」で、直すことが出来るので、何時か紹介します。
「変更されました」ラベルを、赤い枠に変えます。
この方法は、将来「最も重要なイベント」になるので、簡単な今の内に覚えておきましょう。
方法は、今までとは全然違います。実は、こちらの方が、「標準の手順」になります。今までの手順は、「簡易的な手順」です。
「IDE のデザイン」に戻って、「変更されました」ラベルを、クリックします(ダブルクリックではありません)。
次に、右ペインにある「プロパティのタブ」の、一番上にある「茶色の雷(§)のアイコン」を、クリックします。
これで、「イベント一覧」が表示されます。一番上に、「DirtyLabel System.Windows.Forms.Label」と表示されているのを、確認してください。
この状態で、一番下にある「表示」カテゴリーの下に、「Paint」というイベントがあるので、ダブルクリックします。
そして、 ソースコードに行って、以下のコードを全て打ち込みます。
/// <summary>
/// DirtyLabel に色々と装飾を行います。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DirtyLabel_Paint(object sender, PaintEventArgs e)
{
if (IsDirty)
{
// 赤色で四角を描画します。
DirtyLabel.BorderStyle = BorderStyle.None;
Rectangle rect = new Rectangle(0, 0,
e.ClipRectangle.Width - 1, e.ClipRectangle.Height - 1);
e.Graphics.DrawRectangle(Pens.Red, rect);
}
else
{
// ディフォルトに戻して置きます。
DirtyLabel.BorderStyle = BorderStyle.FixedSingle;
}
}
実は、この「Paint イベント」は、最も重要な「イベント」と言っても、過言ではありません。
殆どのコントロールに、予め設定されています。そして、何かを描画したい場合は、「唯一無二で必須」のイベントになります。
これ以外のイベントで「描画」した場合は、「描画の結果」は保証されません。
以上で、全て終了です。
お疲れさまでした。m(_ _)m
それでは、「▲ 開始」か「F5」を押下して、動かしましょう。先程とどう違うかを、体験してましょう。この二つのイベントが入るだけで、本格的なアプリケーションになります。
処理としては、非常に標準的なものに成っていますが、これから「自分用」の付加価値を付けるのは、私ではなく自分自身です。頑張ってください。
まとめ。
さぁ、如何でしたでしょうか?。今回は、「本格的なアプリケーション」になったので、初心者の方には、難しかったと思います。
しかし実は、まだまだこれからが、本格的に難しくなったりします。ところが実は、ここ迄が一番重要なんです。何故なら、その後は延長線なので、自由にコントロールを扱うことが出来ます。
ですから、ここ迄を「徹底的」に、マスターしましょう。「 空 」で出来るようになるまで、何回も練習しましょう。
そうすれば、この後のことも比較的楽に、理解できるようになります。
重要なのは、今回作成した「アプリケーションの構成」です。今後、このサイトでは、「MenuStrip」、「StatusStrip」、「SplitContainer」を使った構成が、ディフォルトの構成になります。
まぁ、個人用に、アプリケーションを作るのですから、「大きな一つのアプリケーション」を作るよりも、「小さな沢山のアプリケーション」を作る方が、実用的だと思います。
それでは、この辺でごきげんよう。
コメント