かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

WPF の Window が開いていれば前面に表示する

Ito Blogで紹介されていたWPF の Window が開いていれば前面に表示するですが、自分ならこんなふうに実装するかなぁというのが思いついたのでメモがてらコードを置いておきます。

とりあえず、Applicationクラスが現在開かれているWindowを管理しているので、そこから同じ型のものが含まれるかどうか?というのを判断基準にしてます。
コードは以下のようになります。

namespace SingleWindowsSample
{
    using System;
    using System.Linq;
    using System.Windows;

    public static class WindowManager
    {
        public static void ShowOrActivate<TWindow>()
            where TWindow : Window, new()
        {
            // 対象Windowが開かれているか探す
            var window = Application.Current.Windows.OfType<TWindow>().FirstOrDefault();
            if (window == null)
            {
                // 開かれてなかったら開く
                window = new TWindow();
                window.Show();
            }
            else
            {
                // 既に開かれていたらアクティブにする
                window.Activate();
            }
        }

        // newでインスタンスが作れない時用
        public static void ShowOrActivate<TWindow>(Func<TWindow> factory)
            where TWindow : Window
        {
            // 対象Windowが開かれているか探す
            var window = Application.Current.Windows.OfType<TWindow>().FirstOrDefault();
            if (window == null)
            {
                // 開かれてなかったら開く
                window = factory();
                window.Show();
            }
            else
            {
                // 既に開かれていたらアクティブにする
                window.Activate();
            }
        }
    }
}

使う側は、以下のような感じで使います。

// 単純にnewでインスタンス化できるWindowの場合
WindowManager.ShowOrActivate<Window1>();

// ラムダ式で任意のインスタンス生成方法を指定する場合
WindowManager.ShowOrActivate<Window1>(() => new Window1());


当然のことですが、ItoさんのBlogで書いてある方法のほうがパフォーマンスはいいと思います。ただ、個人的には同時に開くWindowの数なんてたかが知れているので、この方法でも開かれているウィンドウを走査するのがボトルネックになることはないかなぁと思います。