いきなり投稿が一ヶ月半開くという体たらく…
仕事が忙しいせいです私のせいじゃありません
TaskDialog が使用できるかどうか判定するには
本当は 1 回目で書いておくべきでしたが、すっかり忘れていたためここで紹介します。
TaskDialog は Windows Vista 以降でしかサポートされていません。ですので、実行時に TaskDialog が使用できるかどうかを確かめ、使用できれば TaskDialog を使用、できなければ代替 UI を… などという状況が想像できます。
そんなときは、TaskDialog クラスに用意されている次の静的プロパティを使用すると便利です。
public static bool IsPlatformSupported { get; }
ズバリ、動作している環境が TaskDialog を使用できるかどうかを示す bool 値を返してくれます (と言っても、中身は Environment.OSVersion.Version.Major >= 6
してるだけですが…)。
TaskDialogRadioButton
その名の通り、ラジオ ボタンを表示できます。
ただし、TaskDialog 上でラジオ ボタンを使って何かを選択させる UI は今まで見たことないので、使いどころは少ないかもしれません。と言うより、ユーザーにアクションを選択させたいのであれば、後述の CommandLink を使うべきです。
そして、前回も乗せたこの図を見るとおわかり頂けると思いますが、TaskDialogRadioButton は TaskDialogButtonBase を継承しています。そして、新しいメンバーは何もありません。。。
ですので、そのまま使うと System.Windows.Controls.RadioButton のように IsChecked プロパティからチェック状態を判定… などということができません。やはり使いどころはあまりなさそう。
var dialog = new TaskDialog(); dialog.Caption = "TaskDialog という選択"; dialog.InstructionText = "ダイアログが表示されました"; dialog.Text = "アナタはきのこ派? たけのこ派?"; var result = ""; var ctr1 = new TaskDialogRadioButton("radio1", "手が汚れないきのこで"); ctr1.Click += (sender, e) => result = ctr1.Name; dialog.Controls.Add(ctr1); var ctr2 = new TaskDialogRadioButton("radio2", "自立できるたけのこで"); ctr2.Click += (sender, e) => result = ctr2.Name; dialog.Controls.Add(ctr2); var ctr3 = new TaskDialogRadioButton("radio3", "アルフォートでいいじゃん"); ctr3.Click += (sender, e) => result = ctr3.Name; dialog.Controls.Add(ctr3); dialog.Show();
result などという変数を用意して、ラジオ ボタンがクリックされたらその名前を result に突っ込むという苦肉の策。これで、ダイアログが閉じたときにどのラジオ ボタンが選択されていたのか判定できますが…
やっぱり CommandLink の方がいいです。私はたぶん使わないです、TaskDialogRadioButton。
TaskDialogProgressBar
続いて、プログレス バーです。
var dialog = new TaskDialog(); dialog.Caption = "TaskDialog という選択"; dialog.InstructionText = "ダイアログが表示されました"; dialog.Text = "処理中は ProgressBar を出せます。"; var button = new TaskDialogButton("button", "Completed"); button.Enabled = false; button.Click += (sender, e) => dialog.Close(); dialog.Controls.Add(button); var bar = new TaskDialogProgressBar(0, 50, 0); dialog.ProgressBar = bar; dialog.Opened += (sender, e) => Observable .Generate(0, i => i <= 50, i => ++i, i => i, _ => TimeSpan.FromMilliseconds(100)) .Subscribe(i => bar.Value = i, () => button.Enabled = true); dialog.Show();
TaskDialogProgressBar のコンストラクター引数は、順に最小値、最大値、現在値です。
例では、最小値 0、最大値 50、現在値 0 で初期化、TaskDialog が開かれたら 100 ミリ秒ごとに現在値を 1 ずつ追加しています (ついでに、最大値になるまでボタンを無効化していたり)。
また、例では TaskDialogProgressBar を TaskDialog クラスの ProgressBar プロパティに設定していますが、他のコントロールと同様に TaskDialog.Controls.Add() メソッドで追加することもできます。
ただし、TaskDialog 上に表示できる ProgressBar は 1 つだけです。2 つ以上 Add することはできますが、後から追加した ProgressBar しか UI 上に表示されませんのでご注意ください。
TaskDialogCommandLink
そして、TaskDialog と言ったらコレ、TaskDialogCommandLink です。
var dialog = new TaskDialog(); dialog.Caption = "TaskDialog という選択"; dialog.InstructionText = "TaskDialog といえばコレ、CommandLink です"; dialog.Text = "Visual Studio 2010 の応答が無くなった!"; var link1 = new TaskDialogCommandLink("link1", "プログラムを終了します"); link1.Click += (sender, e) => dialog.Close(); dialog.Controls.Add(link1); var link2 = new TaskDialogCommandLink("link2", "プログラムの応答を待ちます"); link2.Click += (sender, e) => dialog.Close(); dialog.Controls.Add(link2); var link3 = new TaskDialogCommandLink("link3", "コンピューターを窓から投げ捨てます"); link3.Click += (sender, e) => dialog.Close(); link3.Default = true; dialog.Controls.Add(link3); dialog.Show();
OS が表示する TaskDialog でも、CommandLink のものはよく見かけますね。
使い方は簡単で、表示するテキストを指定して初期化、TaskDialog.Controls.Add() メソッドで追加するだけです。
上記の例では、3 つめの CommandLink を Default に指定しています (青枠出てるのわかります?) ので、この状態で Enter キーを押すとコンピューターを窓から投げ捨てることになります (
また、CommandLink に表示できるのはテキストのみではなく、詳しい説明なども表示できたりします。
var dialog = new TaskDialog(); dialog.Caption = "TaskDialog という選択"; dialog.InstructionText = "TaskDialog といえばコレ、CommandLink です"; dialog.Text = "Visual Studio 2010 の応答が無くなった!"; var link1 = new TaskDialogCommandLink( "link1", "プログラムを終了します", "アナタの 2 時間分の作業がすべて消失します! それでもよろしいのですか? 後悔しませんか? もう少し待ってみてもいいのではないですか?"); link1.Click += (sender, e) => dialog.Close(); link1.UseElevationIcon = true; link1.Default = true; dialog.Controls.Add(link1); var link2 = new TaskDialogCommandLink( "link2", "プログラムの応答を待ちます", "待っても無駄な可能性が高いですよ? それでも待ちますか? 時間勿体ないと思いませんか? 諦めた方が楽になれますよ?"); link2.Click += (sender, e) => dialog.Close(); dialog.Controls.Add(link2); dialog.Show();
コンストラクターのオーバーロードで、第 3 引数に説明用のテキストを指定できます。また、TaskDialogButton と同様に UseElevationIcon プロパティで UAC の特権昇格アイコンも表示できます。
ユーザーにアクションを選択させるときに役立ちますので、是非活用して頂きたいです。