FileDialog コントロールを、習得しましょう。

当ページのリンクには広告が含まれています。
「FileDialog コントロールを、習得しましょう。」のアイキャッチ画像。青白い山脈が、遠くまで続く風景。

 こんにちは、皆さん。今日は簡単な「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既に成っています
AutoScaleModeNoneスケールモード
Size1000, 700サイズ
StartPositionCenterScreen初期位置
FontYu Gothic UI, 9ptフォント
TextFileOpenSaveテキスト

 ここ迄は、毎回、同じ設定になります。「 Size 」が、異なるくらいです。

 これらの設定は、27インチのモニター(1920 × 1080)を使った、「デスクトップ」での設定です。   

 ノートパソコン等の場合には、大き過ぎる場合もあるので、自分に合った「サイズ」や「フォント」に変更してください。

 尚、これ以降の設定もそうですが、飽くまでも基本的なことなので、強制ではありません。自分の好みに設定してみましょう。

次に、StatusStrip コントロールを貼ります。

 左ペインの「ツールボックス」から、「StatusStrip」をクリックして、そのままドラッグ&ドロップで「 Form 」の何処かに落とします。自動的に、Form の下のエリアに格納されます。

 その状態で、引き続き右ペインの「プロパティ」を設定します。

(Name)StatusStrip名前
TextStatusStrip任意です
Items(コレクション)クリックします

 このコントロールは、結構難しいので単純には説明できません。詳しいことは、「【C# Form コントロール】先ず、最初に行うこと。」に書いてあるので、先に参照してください。m(_ _)m

 設定は、主に、「項目コレクション エディタ」で行います。プロパティの「Items: (コレクション)」の三点リーダーをクリックすると、表示されます。

 今回、必要なのは、二つの「StatusLabel」です。物にも依りますが、通常は、「2個 ~ 5個」くらいです。

 「項目コレクション エディタ」で、「Status Label 追加(A)」を、二回クリックします。其々、以下のプロパティを設定します。

(Name)MessageStatusLabel名前
BorderSidesRight境界線の位置
SpringTrue最大化
TextAlignMiddleLeftテキストの位置
Text空白テキスト

 

(Name)PainStatusLabel名前
AutoSizeFalse自動サイズ
Size150, 20サイズ
BorderSidesRight境界線の位置
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上 に貼ります。そして、そのまま引き続き右ペインの「プロパティ」を設定します。

NameSplitContainer名前
DockFill結合方法
FixedPanelPanel2固定パネル
SplitterDistance676分割線の位置
SplitterWidth8分割線の幅
BorderStyleFixedSingle境界線の種類
CursorSizeWEマウスのイメージ

Panel1 を設定します。

 そのままの状態で、SplitContainer コントロールの、「分割線」より左側の領域の、「真ん中辺り」をクリックします。ここは、「Panel1」の領域です。

 そして、そのまま引き続き右ペインの「プロパティ」を設定します。

CursorDefaultマウスのイメージ

 今回は、シンプルにこれだけです(笑)。通常の「Panel」と何も変わりません。

Panel2 を設定します。

 更に、そのままの状態で、SplitContainer コントロールの、「分割線」より右側の領域の、「真ん中辺り」をクリックします。ここは、「Panel2」の領域です。

 そして、そのまま引き続き右ペインの「プロパティ」を設定します。

CursorDefaultマウスのイメージ

 こちらも、これだけです。尚、「Panel2」は、基本的に「コマンド類」を入れる領域です。

 私は右利きなので、右側に「コマンド類」を設定しているのですが、左利きの場合は、「Panel1」と「Panel2」を、入れ替えれば良いです。

 後は、必要に応じて、「Panel1」と「Panel2」を入れ替えて、設定すれば良いです。

必要なコントロールを貼って行きます。

 それでは、アプリケーションに必要なコントロールを、「Panel1」と「Panel2」に貼っていきます。

Panel1 に、TextBox を貼ります。

 「Panel1」には、ファイルの内容を表示したり、編集して保存する「TextBox」を貼ります。

 「ツールボックス」から、「TextBox」をクリックして、Form上 の「Panel1」に貼ります。そして、そのまま引き続き右ペインの「プロパティ」を設定します。

(Name)MainTextBox名前
HideSelectionFalse選択の非表示
MaxLength0最大文字数
MultilineTrue複数行の有無
DockFill結合方法
BorderStyleNone境界線の種類
Font游ゴシック, 12ptフォント
ScrollBarsBothスクロールバー

 基本的に「TextBox」は、Windows 付属の「メモ帳」と、同等の機能を持っています。多少の機能制限はあるものの、軽量で非常に使い易いコントロールです。

Panel2 に、コマンド類を貼って行きます。

 これから Form 上の「Panel2」に、色んなコントロールを貼って行くのですが、必ずしもその設定通りになるとは、限りません。

 ですから、多少の誤差はあると思いますが、余り気にしなくても構いません。自分の環境に、最も適切な値に「再設定」して下さい。例えば、ノートパソコンとかの場合は。

 以下の値は、飽くまでも、デスクトップ(1920 × 1080)としての基本的な値です。幾らでも、変更は可能です(Location や Size 等)。

STEP
クリアします。

 「ツールボックス」から、「Button」をクリックして、Form 上の「Panel2」に貼ります。そして、そのまま引き続き右ペインの「プロパティ」を設定します。

(Name)ClearButton名前
Location70, 30位置
Size160, 40サイズ
Textクリアテキスト

  これは、「MainTextBox」のテキストを、クリア(初期状態)する為のものです。

STEP
ファイルを開きます。

 次に、「Button」をクリックして、Form 上の「Panel2」に貼ります。引き続き「プロパティ」を設定します。

(Name)FileOpenButton名前
Location70, 100位置
Size160, 40サイズ
Textファイルを開くテキスト

 この「Button」は、「OpenFileDialog コントロール」を、表示する為のものです。ファイル自体は、「OpenFileDialog コントロール」で選択します。

STEP
テキストの「変更状態」を表示します。

 次に、「Label」をクリックして、Form 上の「Panel2」に貼ります。引き続き「プロパティ」を設定します。

(Name)DirtyLabel名前
EnabledFalse稼働の有無
AutoSizeFalseサイズの自動化
Location70, 170位置
Size160, 40サイズ
BorderStyleFixedSingle境界線の種類
ForeColorRed前景色
Text変更されましたテキスト
TextAlignMiddleCenterテキストの位置

 このラベルは、「テキストが変更されたかどうか」を、表示するためのラベルです。この手の「フラグ」は通常は、「表」に出て来ないものですが、練習用なので表示してみました。

STEP
名前を付けて保存します。

 次に、「Button」をクリックして、Form 上の「Panel2」に貼ります。引き続き「プロパティ」を設定します。

(Name)FileSaveButton名前
Location70, 240位置
Size160, 40サイズ
Text名前を付けて保存テキスト

 この「Button」も、「SaveFileDialog コントロール」を、表示する為のものです。ファイル自体は、「SaveFileDialog コントロール」で選択します。

STEP
検索文字列を入力します。

 次に、「TextBox」をクリックして、Form 上の「Panel2」に貼ります。引き続き「プロパティ」を設定します。

(Name)SearchTextBox名前
WordWrapFalse折り返しの有無
Location50, 320位置
Size200, 27サイズ

 検索したい「文字列」を、入力するエリアです。

STEP
大文字と小文字を区別します。

 次に、「CheckBox」をクリックして、Form 上の「Panel2」に貼ります。引き続き「プロパティ」を設定します。

(Name)UpLowLetterCheckBox名前
Location52, 370位置
Size196, 24サイズ
Text大文字と小文字を区別するテキスト

 検索時に、大文字と小文字を、区別するかどうかを選択します。

STEP
文字列を検索します。

 次に、「Button」をクリックして、Form 上の「Panel2」に貼ります。引き続き「プロパティ」を設定します。

(Name)SearchButton名前
Location70, 420位置
Size160, 40サイズ
Text文字列の検索テキスト

 文字列を検索して、「強調表示」します。一度のクリックで、一回検索します。文章の最後まで到達すると、自動的に「ラップアラウンド」します。

STEP
右端で折り返します。

 次に、「CheckBox」をクリックして、Form 上の「Panel2」に貼ります。引き続き「プロパティ」を設定します。

(Name)WordWrapCheckBox名前
Location87, 500位置
Size125, 24サイズ
CheckedTrueチェックの有無
ForeColorGreen前景色
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」を使った構成が、ディフォルトの構成になります。

 まぁ、個人用に、アプリケーションを作るのですから、「大きな一つのアプリケーション」を作るよりも、「小さな沢山のアプリケーション」を作る方が、実用的だと思います。

 それでは、この辺でごきげんよう。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次