今回は、正規表現テストツールのソースコードについて解説します。
プロジェクト一式のダウンロード
プロジェクト一式は下記からダウンロードが可能です。
プロジェクトを任意のフォルダに解答の上、RegexTest.sln をダブルクリックするとVisual Studio 2019 が立ち上がり、ソースコードが表示されます。
ソースコードの解説
まず、使い方について簡単に操作方法について復習しておきましょう。

クラス構成
ソースコードを解説する前に、クラスの構成について簡単に触れておきたいと思います。
今回は画面のクラス(MainForm)の他、画面上のコントロールの値を保存/復元するための ControlValueManager クラスの2本立てになっています。

今回は1つのファイル(MainForm.cs)に2つのクラスを記述しましたが、他のプログラムで流用する事を考えるなら、別ファイル(例えば、ControlValueManager.cs)にしておく方が良いと思います。
ソースコード全体
今回は300行ちょっとのソースコード量になっています。
1つ1つのメソッドはそれほど難しい事をしていませんので、コメントと合わせて読み進めて頂ければ、どんなことをやっているか分かると思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Text.RegularExpressions; using System.IO; namespace RegexTest { public partial class MainForm : Form { //ヘルプファイルの名前 private const string HELP_FILE = @".\Help.txt"; //コントロールの値管理用クラス private ControlValueManager _manager; /// <summary> /// コンストラクタ /// </summary> public MainForm() { InitializeComponent(); } /// <summary> /// フォームロード処理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MainForm_Load(object sender, EventArgs e) { //uxSource TextBoxにドラッグ&ドロップ機能を付加 SetDragDrop(uxSource); //ヘルプ表示のパネルを閉じる uxMainSplit.Panel2Collapsed = true; //抽出ラジオボタンを選択状態に設定 uxIsExtract.Checked = true; //保存対象のコントロールの定義 Control[] controls = new Control[] { uxIsExtract,uxIsReplace,uxIsHelp,uxRegexString,uxReplaceString,uxSourceCode, uxIsSingleLineMode,uxIsMultiLineMode,uxIsIgnoreCase,uxIsRightToLeft, uxSource,uxResult }; //ヘルプファイルの読み込み uxHelp.Text = (File.Exists(HELP_FILE)) ? File.ReadAllText(HELP_FILE, Encoding.GetEncoding("shift-jis")) : ""; //コントロールの値を復元 _manager = new ControlValueManager(controls); _manager.Restore(); } /// <summary> /// 画面クローズ処理(画面右上の×ボタンクリック時) /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MainForm_FormClosed(object sender, FormClosedEventArgs e) { //コントロールの値を保存 _manager.Store(); } /// <summary> /// 実行ボタンクリック処理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void uxExecute_Click(object sender, EventArgs e) { try { //チェックボックスからオプションを生成 RegexOptions options = RegexOptions.None; if (uxIsSingleLineMode.Checked) options = options | RegexOptions.Singleline; if (uxIsMultiLineMode.Checked) options = options | RegexOptions.Multiline; if (uxIsIgnoreCase.Checked) options = options | RegexOptions.IgnoreCase; if (uxIsRightToLeft.Checked) options = options | RegexOptions.RightToLeft; //チェックボックスの状態からオプションを組み立てる string option_str = "RegexOptions." + options.ToString().Replace(" ", "").Replace(",", " | RegexOptions."); string mark = (uxRegexString.Text.Contains("\\")) ? "@" : ""; uxSourceCode.Text = string.Format("Regex({0}\"{1}\",{2}); ", mark, uxRegexString.Text, option_str); //抽出のラジオボタンが選択されているかチェック if (uxIsExtract.Checked) { //正規表現を使った抽出の実行 uxResult.Text = Extract(uxRegexString.Text, uxSource.Text, options); } else { //正規表現を使った置換の実行 uxResult.Text = Replace(uxRegexString.Text, uxSource.Text, uxReplaceString.Text, options); } } catch (Exception exp) { ShowErrorMessage(exp); } } /// <summary> /// 正規表現を使った抽出処理 /// </summary> /// <param name="pattern"></param> /// <param name="sour"></param> /// <param name="options"></param> /// <returns></returns> private string Extract(string pattern,string sour, RegexOptions options = RegexOptions.None) { //正規表現クラスのインスタンス化 Regex regex = new Regex(pattern, options); string result = ""; //一致する文字列があったかをチェック if (regex.IsMatch(sour)) { //一致する文字列を全て抽出 MatchCollection matches = regex.Matches(sour); //一致する文字列を改行コードで結合 foreach(Match match in matches) { result += match.Value + Environment.NewLine; } } return result; } /// <summary> /// 正規表現を使った置換処理 /// </summary> /// <param name="pattern"></param> /// <param name="sour"></param> /// <param name="str"></param> /// <param name="options"></param> /// <returns></returns> private string Replace(string pattern, string sour,string str,RegexOptions options = RegexOptions.None) { //正規表現クラスのインスタンス化 Regex regex = new Regex(uxRegexString.Text, options); return regex.Replace(sour, str); } /// <summary> /// ヘルプ表示チェックボックスのクリック処理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void uxIsHelp_CheckedChanged(object sender, EventArgs e) { //ヘルプが開いていたら閉じる。閉じていたら開く。 uxMainSplit.Panel2Collapsed = ! uxIsHelp.Checked; } /// <summary> /// 指定したコントロールへのファイルドラッグ&ドロップの設定 /// </summary> /// <param name="control"></param> private void SetDragDrop(Control control) { //ドラッグ&ドロップを受け付けられるようにする control.AllowDrop = true; //ドラッグが開始された時のイベント処理(マウスカーソルをドラッグ中のアイコンに変更) control.DragEnter += (s, e) => { //ファイルがドラッグされたとき、カーソルをドラッグ中のアイコンに変更し、そうでない場合は何もしない。 e.Effect = (e.Data.GetDataPresent(DataFormats.FileDrop)) ? DragDropEffects.Copy : e.Effect = DragDropEffects.None; }; //ドラッグ&ドロップが完了した時の処理(ファイル名を取得し、ファイルの中身をTextプロパティに代入) control.DragDrop += (s, e) => { //ドロップされたすべてのファイル名を取得する string[] filenames = (string[])e.Data.GetData(DataFormats.FileDrop, false); //タグの一覧を表示 control.Text = File.ReadAllText(filenames[0], Encoding.GetEncoding("shift-jis")); }; } /// <summary> /// 単一行モードチェックボックスクリック処理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void uxIsSingleLineMode_CheckedChanged(object sender, EventArgs e) { //単一行モードと複数行モードの両方にチェックがある場合 if(uxIsSingleLineMode.Checked && uxIsMultiLineMode.Checked) { //複数行モードのチェックを外す uxIsMultiLineMode.Checked = false; } } /// <summary> /// 複数行モードチェックボックスクリック処理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void uxIsMultiLineMode_CheckedChanged(object sender, EventArgs e) { //単一行モードと複数行モードの両方にチェックがある場合 if (uxIsSingleLineMode.Checked && uxIsMultiLineMode.Checked) { //単一行モードのチェックを外す uxIsSingleLineMode.Checked = false; } } /// <summary> /// エラーメッセージの表示 /// </summary> /// <param name="exp"></param> private void ShowErrorMessage(Exception exp) { MessageBox.Show(exp.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// <summary> /// コントロールの値を管理(フェイル保存/復旧)するクラス /// </summary> public class ControlValueManager { //列名を定義 private const string TABLE = "ControlValue"; private const string NAME = "name"; private const string VALUE = "value"; //コントロールの値を保存するファイル名 private const string FILE_PATH = @".\ControlValues.xml"; //対象となるコントロールを格納しておくList private List<Control> _controls; //コントロール名と値を格納しておくDataTable private DataTable _variable; public ControlValueManager(Control[] controls) { //引数で渡されたコントロールを自分の中に取り込む _controls = new List<Control>(); _controls.AddRange(controls); //ファイルへの読み書きに使うDataTableの定義 _variable = new DataTable(TABLE); _variable.Columns.Add(NAME); _variable.Columns.Add(VALUE); } /// <summary> /// コントロールの値をファイルに保存 /// </summary> public void Store() { try { //DataTable の中身をクリア _variable.Clear(); //コントロールの値を取り出すループ foreach (Control control in _controls) { //DataRow の生成 DataRow dr = _variable.NewRow(); //コントロール名の代入 dr[NAME] = control.Name; //コントロールの種類に応じて、値を取り出してDataRowに代入 if (control.GetType() == typeof(TextBox)) dr[VALUE] = control.Text; else if (control.GetType() == typeof(ComboBox)) dr[VALUE] = control.Text; else if (control.GetType() == typeof(CheckBox)) dr[VALUE] = ((CheckBox)control).Checked.ToString(); else if (control.GetType() == typeof(RadioButton)) dr[VALUE] = ((RadioButton)control).Checked.ToString(); //DataTableにDataRowを登録 _variable.Rows.Add(dr); } //DataTableの内容をファイルに保存 _variable.WriteXml(FILE_PATH); } catch { } } /// <summary> /// コントロールの値をファイルから復元 /// </summary> public void Restore() { //保存済みファイルが存在するかチェック if(File.Exists(FILE_PATH) == false) { return; } try { //ファイルの内容をDataTableに読み込む _variable.ReadXml(FILE_PATH); //コントロールの値を復旧するループ foreach (Control control in _controls) { //DataTableからコントロール名を検索 DataRow dr = _variable.AsEnumerable().FirstOrDefault(i => i[NAME].ToString() == control.Name); //コントロール名が見つかったら、コントロールに値を代入 if (dr != null) { //コントロールの種類に応じた値を復元 if (control.GetType() == typeof(TextBox)) control.Text = dr[VALUE].ToString(); else if (control.GetType() == typeof(ComboBox)) control.Text = dr[VALUE].ToString(); else if (control.GetType() == typeof(CheckBox)) ((CheckBox)control).Checked = bool.Parse(dr[VALUE].ToString()); else if (control.GetType() == typeof(RadioButton)) ((RadioButton)control).Checked = bool.Parse(dr[VALUE].ToString()); } } } catch { } } } } |
System.Text.RegularExpressionsの記述
正規表現を使う場合は、System.Text.RegularExpressions名前空間をソースコードの冒頭に記述しておきます。
1 |
using System.Text.RegularExpressions; |
記述しない場合は、いちいち正規表現関連のクラスや列挙型(Enum)の前に名前空間を記述しなければならなくなるので面倒です。
FormLoadとFormCloseの処理
FormLoadでは次の4つのことを行っています。
- プログラム起動におけるコントロールの初期設定
- テキストボックスに対してドラッグ&ドロップの機能付加
- ヘルプファイルの読み込み
- コントロールの値の復元を行っています。
ControlValueManagerは、あらかじめ値の保存/復元をしたいコントロールを配列で宣言し、それをインスタンス生成時の引数として渡した後、Restoreメソッドを呼ぶという使い方になります。
以下がFormLoadのソースコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
//uxSource TextBoxにドラッグ&ドロップ機能を付加 SetDragDrop(uxSource); //ヘルプ表示のパネルを閉じる uxMainSplit.Panel2Collapsed = true; //抽出ラジオボタンを選択状態に設定 uxIsExtract.Checked = true; //保存対象のコントロールの定義 Control[] controls = new Control[] { uxIsExtract,uxIsReplace,uxIsHelp,uxRegexString,uxReplaceString,uxSourceCode, uxIsSingleLineMode,uxIsMultiLineMode,uxIsIgnoreCase,uxIsRightToLeft, uxSource,uxResult }; //ヘルプファイルの読み込み uxHelp.Text = (File.Exists(HELP_FILE)) ? File.ReadAllText(HELP_FILE, Encoding.GetEncoding("shift-jis")) : ""; //コントロールの値を復元 _manager = new ControlValueManager(controls); _manager.Restore(); |
一方、FormClose処理では、ControlValueManagerのRestoreメソッドを呼んで、コントロールの値をファイルに書き出しています。
1 2 |
//コントロールの値を保存 _manager.Store(); |
実行ボタンクリック処理
ここでは、
- 各種チェックボックスの状態から正規表現クラスのオプションを組み立てる。
- 正規表現のソースコードを生成し、ソースコード欄に表示する。
- 抽出/置換のラジオボタンの状態に応じて、Extractメソッド、Replaceメソッドを呼び分ける
という事をしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
//チェックボックスからオプションを生成 RegexOptions options = RegexOptions.None; if (uxIsSingleLineMode.Checked) options = options | RegexOptions.Singleline; if (uxIsMultiLineMode.Checked) options = options | RegexOptions.Multiline; if (uxIsIgnoreCase.Checked) options = options | RegexOptions.IgnoreCase; if (uxIsRightToLeft.Checked) options = options | RegexOptions.RightToLeft; //チェックボックスの状態からオプションを組み立てる string option_str = "RegexOptions." + options.ToString().Replace(" ", "").Replace(",", " | RegexOptions."); string mark = (uxRegexString.Text.Contains("\\")) ? "@" : ""; uxSourceCode.Text = string.Format("Regex({0}\"{1}\",{2}); ", mark, uxRegexString.Text, option_str); //抽出のラジオボタンが選択されているかチェック if (uxIsExtract.Checked) { //正規表現を使った抽出の実行 uxResult.Text = Extract(uxRegexString.Text, uxSource.Text, options); } else { //正規表現を使った置換の実行 uxResult.Text = Replace(uxRegexString.Text, uxSource.Text, uxReplaceString.Text, options); } |
正規表現を使った抽出処理
ここでは、正規表現を使った抽出処理をメソッド化しています。
正規表現を使うには、Regrexクラスのインスタンスを生成する必要があります。
生成したインスタンスに対して、IsMachtメソッドを呼ぶと、一致する文字列が存在するかどうかがチェックできます。
また、Matchesメソッドを使う事で、一致する文字列をコレクションとして取得できます。
いちいちIsMatchメソッドで確認せずとも、いきなりMatchesメソッドを呼んで、コレクションのCountが0かどうかで判断するという方法もあります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
private string Extract(string pattern,string sour, RegexOptions options = RegexOptions.None) { //正規表現クラスのインスタンス化 Regex regex = new Regex(pattern, options); string result = ""; //一致する文字列があったかをチェック if (regex.IsMatch(sour)) { //一致する文字列を全て抽出 MatchCollection matches = regex.Matches(sour); //一致する文字列を改行コードで結合 foreach(Match match in matches) { result += match.Value + Environment.NewLine; } } return result; } |
一致した文字列が格納されている MatchCollectionは、Match型として1つ1つ取り出すことができ、Match型のValueプロパティで一致した文字列が取得できます。
今回はForeachで1つづつ取り出し、改行で結合した結果を戻り値にしています。
正規表現を使った置換処理
抽出も置換も正規表現クラスのインスタンスを生成する部分は同じです。
インスタンスを生成した後は、Replaceメソッドを呼ぶだけで置換が行えます。
1 2 3 4 |
//正規表現クラスのインスタンス化 Regex regex = new Regex(uxRegexString.Text, options); return regex.Replace(sour, str); |
ドラッグ&ドロップ機能の付与
このメソッドは今までに何度も登場していますが、引数で指定したコントロールに対して、ドラッグ&ドロップの機能を付与するメソッドです。
ラムダ式を使ってイベントハンドラを記述することで、1つのメソッド内で完結させています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
private void SetDragDrop(Control control) { //ドラッグ&ドロップを受け付けられるようにする control.AllowDrop = true; //ドラッグが開始された時のイベント処理(マウスカーソルをドラッグ中のアイコンに変更) control.DragEnter += (s, e) => { //ファイルがドラッグされたとき、カーソルをドラッグ中のアイコンに変更し、そうでない場合は何もしない。 e.Effect = (e.Data.GetDataPresent(DataFormats.FileDrop)) ? DragDropEffects.Copy : e.Effect = DragDropEffects.None; }; //ドラッグ&ドロップが完了した時の処理(ファイル名を取得し、ファイルの中身をTextプロパティに代入) control.DragDrop += (s, e) => { //ドロップされたすべてのファイル名を取得する string[] filenames = (string[])e.Data.GetData(DataFormats.FileDrop, false); //タグの一覧を表示 control.Text = File.ReadAllText(filenames[0], Encoding.GetEncoding("shift-jis")); }; } |
単一行モードと複数行モードのチェック状態制御
単一行モードとは、対象となる文字列の改行を無視し、単一の文字列として扱うモードです。
一方複数行モードは、改行で区切られている事を前提にしたモードになります。
Regrexクラスのオプションでこれらを指定できるのですが、単一モードと複数行モードの両方を省略することは出来ても、両方にチェックを入れることは出来ません。
両方チェックを入れたからと言って特にエラーにはなりませんが、どちらが優先されるのか分からないので、片方にチェックが入った時、もう片方のチェックを外すという状態制御を行っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
private void uxIsSingleLineMode_CheckedChanged(object sender, EventArgs e) { //単一行モードと複数行モードの両方にチェックがある場合 if(uxIsSingleLineMode.Checked && uxIsMultiLineMode.Checked) { //複数行モードのチェックを外す uxIsMultiLineMode.Checked = false; } } /// <summary> /// 複数行モードチェックボックスクリック処理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void uxIsMultiLineMode_CheckedChanged(object sender, EventArgs e) { //単一行モードと複数行モードの両方にチェックがある場合 if (uxIsSingleLineMode.Checked && uxIsMultiLineMode.Checked) { //単一行モードのチェックを外す uxIsSingleLineMode.Checked = false; } } |
ラジオボタンを使うと、このような制御は必要ありませんが、単一行モードと複数行モードの両方を省略するという事が出来ないので、今回はあえてプログラムで制御しています。
ControlValueManagerクラス
ControlValueManagerクラスは次の様になっています。
コンストラクタの引数で渡したコントロール配列は、内部の_controls に格納されます。
Storeメソッド、Restoreメソッドが呼ばれる際、_controls配列からコントロールを取り出し、_variable にコントロール名とコントロールの値をセットします。
_variable はDataTableなので、Xml形式でファイルを読み書きするメソッド(ReadXmlとWriteXml)が備わっています。
今回は、このメソッドを使ってファイル保存/復元を行っています。

クラスのメンバ変数
クラスの冒頭で、クラス内で使う変数や定数を定義しています。
定数で TABLE、NAME、VALUE を定義していますが、これはDataTableの名前と列名になります。
FILE_PATH はファイルのパスですが、プログラムを実行した時のカレントフォルダ(EXEの場所)にファイルを置きたいので、”.\” をファイル名の先頭に付加しています。
また、DataTableの内容をファイル保存する時、DataTableに名前が無いとエラーになるため、ここで定数として定義してます。
NAMEとVALUEは列名なのでわざわざ定数定義する必要は無いという考えも有りますが、後に列名を変更する際、1か所修正するだけで済むように定数で定義しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//列名を定義 private const string TABLE = "ControlValue"; private const string NAME = "name"; private const string VALUE = "value"; //コントロールの値を保存するファイル名 private const string FILE_PATH = @".\ControlValues.xml"; //対象となるコントロールを格納しておくList private List<Control> _controls; //コントロール名と値を格納しておくDataTable private DataTable _variable; |
コンストラクタ
コンストラクタでは、引数で渡されたコントロール配列を _controls に格納するとともに、DataTableのインスタンスを生成し、列を追加しています。
1 2 3 4 5 6 7 8 |
//引数で渡されたコントロールを自分の中に取り込む _controls = new List<Control>(); _controls.AddRange(controls); //ファイルへの読み書きに使うDataTableの定義 _variable = new DataTable(TABLE); _variable.Columns.Add(NAME); _variable.Columns.Add(VALUE); |
Storeメソッド
Storeメソッドでは、_control配列からコントロールを取り出し、Controlの型ごとに保存したい値を取り出し、DataTableに格納しています。
最初に _variable.Clear() で中身をクリアしていますが、これは Storeメソッドが複数回呼ばれた際、前の値が残っていてエラーになることを避けるためです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
//DataTable の中身をクリア _variable.Clear(); //コントロールの値を取り出すループ foreach (Control control in _controls) { //DataRow の生成 DataRow dr = _variable.NewRow(); //コントロール名の代入 dr[NAME] = control.Name; //コントロールの種類に応じて、値を取り出してDataRowに代入 if (control.GetType() == typeof(TextBox)) dr[VALUE] = control.Text; else if (control.GetType() == typeof(ComboBox)) dr[VALUE] = control.Text; else if (control.GetType() == typeof(CheckBox)) dr[VALUE] = ((CheckBox)control).Checked.ToString(); else if (control.GetType() == typeof(RadioButton)) dr[VALUE] = ((RadioButton)control).Checked.ToString(); //DataTableにDataRowを登録 _variable.Rows.Add(dr); } //DataTableの内容をファイルに保存 _variable.WriteXml(FILE_PATH); |
全てのコントロールの処理が終わったら、最後に WriteXmlメソッドで保存しています。
Restoreメソッド
RestoreメソッドはStoreメソッドの逆で、ReadXmlメソッドでファイルから値を読み出した後、_control配列に登録されているコントロールを1つづつ取り出し、値を復元しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
//ファイルの内容をDataTableに読み込む _variable.ReadXml(FILE_PATH); //コントロールの値を復旧するループ foreach (Control control in _controls) { //DataTableからコントロール名を検索 DataRow dr = _variable.AsEnumerable().FirstOrDefault(i => i[NAME].ToString() == control.Name); //コントロール名が見つかったら、コントロールに値を代入 if (dr != null) { //コントロールの種類に応じた値を復元 if (control.GetType() == typeof(TextBox)) control.Text = dr[VALUE].ToString(); else if (control.GetType() == typeof(ComboBox)) control.Text = dr[VALUE].ToString(); else if (control.GetType() == typeof(CheckBox)) ((CheckBox)control).Checked = bool.Parse(dr[VALUE].ToString()); else if (control.GetType() == typeof(RadioButton)) ((RadioButton)control).Checked = bool.Parse(dr[VALUE].ToString()); } |
まとめ
以上でソースコードの解説は終わりです。
他のプログラムに流用しやすいよう、正規表現を使った抽出と置換はメソッド化し、コントロールの値の保存と復元はクラス化しています。
ちょっとした事ですが、このようなメソッドやクラスを使いまわすことで、使いやすいツールが作りやすくなります。
みなさんも色々なメソッドやクラスを作って、資産を増やしていきましょう。