前回の続きになります。今回は、TaskDialog をもう少しカスタマイズしてみます。
TaskDialog のコントロール
TaskDialog の要素には、前回紹介した Text、InstructionText、StandardButtons など、予め使える形で用意されているものもありますが、より複雑な要素を追加することができます。TaskDialog の Controls プロパティです。
public DialogControlCollectionControls { get; }
TaskDialogControl の派生クラスをコレクションに追加すると、そのコントロールを TaskDialog 上に表示できます。TaskDialogControl とその派生クラスは以下の図のようになります。
この中で、Controls コレクションに追加し TaskDialog 上に表示できるコントロールは
- 図中の青のクラス
- 図中の青のクラスから派生したクラス
- 図中の赤のクラスから派生したクラス
となります。
そのため、例えば TaskDialogButton を継承したオリジナルのクラスを作成し、TaskDialog 上に表示することもできます (ただし、派生クラスと言っても外観まで作り込めるわけではありませんので、使いどころは多くないかもしれませんが)。
ちなみに、上記条件以外のクラス (例えば TaskDialogBar クラス) のインスタンスを Controls コレクションに追加すると、TaskDialog.Show() したときに InvalidOperationException がスローされます。
これから、図中の青のクラスを中心に、TaskDialog 上で使用できるコントロールを紹介してきます。
TaskDialogButton で独自のボタンを配置する
TaskDialog には StandardButtons プロパティがあり、一般的なメッセージ ダイアログで使用される [OK] [キャンセル] [はい] [いいえ] [再試行] [閉じる] ボタンを組み合わせて表示することができます (TaskDialogStandardButtons 列挙値)。
大抵の場合はこれで事足りるかと思いますが、独自の文言を持つボタンを用意したい場合や、クリックされたときに何らかの処理を行いたい場合は、TaskDialogButton クラスを使用することでそれらを実現できます。
早速ですが、コードの例を示します。
var dialog = new TaskDialog(); dialog.Caption = "契約のご確認"; dialog.InstructionText = "キュウべえは言いました"; dialog.Text = "僕と契約して、魔法少女になってよ!"; var contractButton = new TaskDialogButton(); contractButton.Text = "契約"; contractButton.Default = true; contractButton.Click += (sender, e) => dialog.Close(TaskDialogResult.Ok); dialog.Controls.Add(contractButton); var cancelButton = new TaskDialogButton(); cancelButton.Text = "その必要はないわ"; cancelButton.Click += (sender, e) => dialog.Close(TaskDialogResult.Cancel); dialog.Controls.Add(cancelButton); var result = dialog.Show();
contractButton、cancelButton という 2 つのボタンを作成し (元ネタはお察しください)、TaskDialog クラスの Controls コレクションに追加しました。
Text プロパティでボタンの文言を指定できます。
Default プロパティに true を指定すると既定のボタンになります。当然ですが、複数のボタンの Default プロパティを true にすると InvalidOperationException がスローされますのでご注意ください。
ボタンがクリックされると、Click イベントが発生します。クリック時に実行したい処理はここに書きましょう。今回の例ではダイアログを閉じる処理だけですが。。。
また、TaskDialogButton の話から外れますが、TaskDialog の Close メソッドは結果を指定することができます。プログラムから TaskDialog を閉じる場合は、Close メソッドの引数で結果 (TaskDialogResult 列挙値) を与えると、Show メソッドの戻り値としてその結果を受け取ることができます。
もちろん、結果を指定せずに (= 引数を指定せずに) 閉じることもできます。その場合、Show メソッドの戻り値は TaskDialogResult.Cancel です。
さらにカスタマイズ
TaskDialogButton クラスは、TaskDialogButtonBase クラスを継承しています。これらを継承し、独自のボタン クラスを作ることもできます。
(上でも言いましたが、UI をカスタマイズできるわけではないので、あまり使いどころはないかもしれません)
これを利用し、先ほどの contractButton を以下のように置き換えることができます。
public class ContractTaskDialogButton : TaskDialogButtonBase { public ContractTaskDialogButton(TaskDialog owner) : this(owner, "contractTaskDialogButton", "契約") { } public ContractTaskDialogButton(TaskDialog owner, string name, string text) : base(name, text) { this.Default = true; this.Click += (sender, e) => { if (owner != null) owner.Close(TaskDialogResult.Ok); }; } }
var contractButton = new ContractTaskDialogButton(dialog); dialog.Controls.Add(contractButton);
この程度であれば何の意味もありませんが、ボタンのクリック時に複雑な処理を実行したい場合などでは、この方法の方が綺麗に作れるかと思います。
ちなみに、TaskDialogButton クラスと TaskDialogButtonBase クラスの違いは、UseElevationIcon プロパティがあるかないかだけです。UseElevationIcon プロパティに true を指定すると、以下のように UAC の特権昇格を示す盾のアイコンが表示されます。
var contractButton = new TaskDialogButton(); contractButton.Text = "契約"; contractButton.Default = true; contractButton.Click += (sender, e) => dialog.Close(TaskDialogResult.Ok); contractButton.UseElevationIcon = true; dialog.Controls.Add(contractButton);
そしてもう一点、これまた TaskDialogButton クラスと直接関係ありませんが、[×] ボタンには注意が必要です。上記例ではダイアログに [×] ボタンが無いのにお気付きでしたでしょうか?
StandardButtons プロパティを使用せず、TaskDialogButton クラスをはじめとしたコントロールを使用する場合、既定ではダイアログの [×] ボタンが表示されません。表示させたい場合は、TaskDialog.Cancelable プロパティに true を指定しましょう。
今回は、TaskDialogControl についてと、その派生クラスのひとつである TaskDialogButton を紹介しました。次回は… TaskDialogRadioButton 辺りを。たぶん。