トップ回答者
ウィンドウを重複起動させない方法

質問
-
ウィンドウをモードレスでかならず1つだけしか表示させない良い方法を探しております。
例えば、以下のコードのようにボタンを押すと
モードレスで別のウィンドウが立ち上がるようにしています。Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click Dim w = New SubWindow() w.Show() End Sub
しかし、これではボタンを押す度にSubWindowが開いてしまいます。
すでにSubWindowが開いているときは新しいウィンドウを開かないようにしたいです。方法として次の3通りを考えました。
1.Application.Current.WindowsをFor文でまわしてすでにインスタンスが存在していないかどうか調べる
2.SubWindowのインスタンスを管理するためのフィールドをMainWindowに準備する
3.SubWindowクラスをシングルトンで設計し、呼び出し用の共有メソッドshowを作る1は最もシンプルですが、VB6以前ではSubWindow.showで要件を満たすことができただけに
.netの方が新しいのになんだかなと思ってしまいます。
※ちなみにVB6のSubWindow.Showのように使用する方法として、
My.Windows.SubWindow.Show()ということ方法でウィンドウの重複起動しないようにすることが可能のようですが
実際ためしてみるとMy.Windows.SubWindow.Show()はSubWindowを閉じたあともう一度呼ぶと
エラーが発生してしまいました。2はウィンドウの種類を増やす度にMainWindowが管理するフィールドが増えていくので
あまり良い方法とは思えません。3はSubWindowを利用する側は便利ですが、SubWindowを作る側の手間が若干増えてしまうのが懸念です。
モードレスのウィンドウを1つだけ表示したいとき、
みなさんはどのような方法を用いておられるのでしょうか。
よろしくお願い致します
回答
-
Window クラスがそのように実装されているため、同じインスタンスを使い回すことはできません。
従って、My.Windows.SubWindow.Show() では、閉じた後に呼び出すと例外が発生します。
VB6 の頃と使い勝手が微妙だと言われても、Form(Window) の実装が違うので仕方がありません。(Form(Window) は VB だけでなく、C# などでも共通の実装であるため、VB.NET だけが別の動きをすることはできません)クラスごと、表示箇所ごとに実装するのが面倒だというのであれば、1 の実装をヘルパーメソッドとしてどこかに作ればよいでしょう。
以下はその一例ですが、LINQ を使っていることと、弱点があるかどうかをきちんと検証していないことと、ほかによりよい方法があるかどうか判断できていないことがあるのでご留意ください。Public Class WindowHelper Public Shared Sub ShowWindow(Of T As {Window, New})() If Application.Current.Windows.OfType(Of T).Any() Then Exit Sub Dim w As New T() w.Show() End Sub End Class
- 編集済み AzuleanMVP 2013年1月20日 21:57
- 回答の候補に設定 佐伯玲 2013年1月21日 4:19
- 回答としてマーク 佐伯玲 2013年1月28日 2:34
すべての返信
-
Window クラスがそのように実装されているため、同じインスタンスを使い回すことはできません。
従って、My.Windows.SubWindow.Show() では、閉じた後に呼び出すと例外が発生します。
VB6 の頃と使い勝手が微妙だと言われても、Form(Window) の実装が違うので仕方がありません。(Form(Window) は VB だけでなく、C# などでも共通の実装であるため、VB.NET だけが別の動きをすることはできません)クラスごと、表示箇所ごとに実装するのが面倒だというのであれば、1 の実装をヘルパーメソッドとしてどこかに作ればよいでしょう。
以下はその一例ですが、LINQ を使っていることと、弱点があるかどうかをきちんと検証していないことと、ほかによりよい方法があるかどうか判断できていないことがあるのでご留意ください。Public Class WindowHelper Public Shared Sub ShowWindow(Of T As {Window, New})() If Application.Current.Windows.OfType(Of T).Any() Then Exit Sub Dim w As New T() w.Show() End Sub End Class
- 編集済み AzuleanMVP 2013年1月20日 21:57
- 回答の候補に設定 佐伯玲 2013年1月21日 4:19
- 回答としてマーク 佐伯玲 2013年1月28日 2:34