次の方法で共有


ウィンドウを重複起動させない方法

質問

2013年1月20日日曜日 16:49

ウィンドウをモードレスでかならず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つだけ表示したいとき、
みなさんはどのような方法を用いておられるのでしょうか。
よろしくお願い致します

すべての返信 (2)

2013年1月20日日曜日 21:55 ✅回答済み

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

2013年1月28日月曜日 2:34

こんにちは、ひょうじめいx さん
フォーラムオペレータの佐伯 玲 です。

その後Azulean さんからの情報はご確認いただけたでしょうか?
参考になる情報だと思われたので勝手ながら私のほうで「回答としてマーク」とさせて頂きました。

一旦「回答としてマーク」をさせてはいただきましたが寄せられた情報をお試しいただき進展がございましたら引き続きこちらのスレッドへご返信くださいませ。

宜しくお願いいたします。
__________________________
日本マイクロソフト株式会社 フォーラム オペレータ 佐伯 玲