最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

WPF中實現(xiàn)單例窗口的解決方案

 更新時間:2025年08月07日 08:23:34   作者:悠然小熠  
在WPF企業(yè)級應用開發(fā)中,我們常常需要確保某個窗口在同一時間只能有一個實例存在,同時還需要支持窗口的關聯(lián)關閉,在這里,我們實現(xiàn)線程安全的單例窗口管理、完善的父子窗口生命周期控制以及靈活的參數(shù)化窗口構(gòu)造,為WPF應用提供一套健壯的窗口管理解決方案

一、前言

在WPF企業(yè)級應用開發(fā)中,我們常常需要確保某個窗口在同一時間只能有一個實例存在,同時還需要支持窗口的關聯(lián)關閉(關閉父窗體時,所有子窗體也會關閉)。

為了實現(xiàn)這些需求,我們采用一種侵入性較低的實現(xiàn)方式,通過創(chuàng)建一個通用的WindowSingletonBase類來管理窗口的單例行為。

在這里,我們實現(xiàn)線程安全的單例窗口管理、完善的父子窗口生命周期控制以及靈活的參數(shù)化窗口構(gòu)造,為WPF應用提供一套健壯的窗口管理解決方案。

二、實現(xiàn)目標

1. 單例窗口實現(xiàn)

  • 支持無參和有參構(gòu)造
  • 通過GetInstance()方法獲取或創(chuàng)建實例
  • 窗口關閉時自動釋放資源

2. 父子窗口關聯(lián)

  • 建立父子窗口鏈路關系
  • 父窗口關閉時自動關閉所有子窗口
  • 子窗口關閉時自動從父窗口的集合中移除

三、代碼實現(xiàn)

1.創(chuàng)建 WindowSingletonBase 封裝單例邏輯

通過泛型基類WindowSingletonBase<T>封裝單例邏輯,同時提供父子窗口管理功能,既保證了功能的完整性,又不會對業(yè)務窗口類造成過多約束。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;

namespace STC.Common.View.Component
{
    /// <summary>
    /// 窗口單例基類,提供單例管理和父子窗口關聯(lián)功能
    /// </summary>
    /// <typeparam name="T">繼承自Window的窗口類型</typeparam>
    
    public class WindowSingletonBase<T> where T : Window
    {
        // 線程安全鎖
        private static readonly object _lock = new object();
        // 單例實例
        private static T _instance;
        // 窗口構(gòu)造方法
        private static Func<object[], T> _constructor;
        // 窗口所擁有子窗口集合
        private static readonly List<Window> _childWindows = new List<Window>();
        
        /// <summary>
        /// 注冊窗口構(gòu)造函數(shù)
        /// </summary>
        public static void RegisterConstructor(Func<object[], T> constructor)
        {
            lock (_lock)
            {
                _constructor = constructor;
            }
        }

        public static T Instance
        {
            get { return GetInstance(); }
        }
        /// <summary>
        /// 獲取窗口單例實例
        /// </summary>
        public static T GetInstance(params object[] args)
        {
            lock (_lock)
            {
                if (_instance == null || !_instance.IsLoaded)
                {
                    if (_constructor == null)
                    {
                        throw new InvalidOperationException("can not found constructor");
                    }

                    _instance = _constructor(args);
                }
                return _instance;
            }
        }

        /// <summary>
        /// 釋放當前實例
        /// </summary>
        public static void ReleaseInstance()
        {
            lock (_lock)
            {
                if (_instance != null)
                {
                    _instance = null;
                }
            }
        }

        /// <summary>
        /// 添加子窗口并建立父子關系
        /// </summary>
        public static void AddChildWindow(Window childWindow)
        {
            if (childWindow == null)
                throw new ArgumentNullException(nameof(childWindow));

            lock (_lock)
            {
                if (!_childWindows.Contains(childWindow)) 
                {
                    childWindow.Owner = _instance; // 設置父子關系
                    _childWindows.Add(childWindow);
                }
            }
        }
        /// <summary>
        /// 從子窗口集合中移除指定窗口
        /// </summary>
        public static void RemoveChild(Window childWindow)
        {
            lock (_lock)
            {
                if (_childWindows.Contains(childWindow)) 
                {
                    _childWindows.Remove(childWindow);
                }
            }
        }

        /// <summary>
        /// 關閉所有子窗口
        /// </summary>
        public static void CloseAllChildren()
        {
            lock (_lock)
            {

                foreach (var window in _childWindows.ToList()) // ToList避免修改集合
                {
                    if (window != null) 
                    {
                        window.Close();// 觸發(fā)子窗口的Closed事件
                    }
                }
                _childWindows.Clear();
            }
        }

        /// <summary>
        /// 顯示或激活窗口
        /// </summary>
        public static void ShowOrActive()
        {
            if (_instance != null)
            {
                if (_instance.IsVisible)
                {
                    _instance.Activate();
                }
                else
                {
                    _instance.Show();
                }
            }
        }

        /// <summary>
        /// 關閉窗口
        /// </summary>
        public static void CloseWindow()
        {
            if (_instance != null)
            {
                if (_instance.IsVisible)
                {
                    _instance.Close();
                }
            }
        }
    }
}

2.使用案例

在步驟1中,創(chuàng)建了WindowSingletonBase用來管理單例窗口?,F(xiàn)在我們來使用WindowSingletonBase。

在需要單例運行的窗體中,做三件事:

  • 1.注冊構(gòu)造函數(shù)。
  • 2.創(chuàng)建實例
  • 3.重寫OnClose方法(用于釋放資源)

2.1 無參構(gòu)造窗體-使用單例窗體

ParentWindow.cs

public partial class ParentWindow : Window
{
    static ParentWindow()
    {
        // 注冊無參構(gòu)造函數(shù)
        WindowSingletonBase<ParentWindow>.RegisterConstructor(args => new ParentWindow());
    }

    public ParentWindow()
    {
        InitializeComponent();
    }
    /// <summary>
    /// 聲明單例窗口 Instance
    /// </summary>
    public static ParentWindow CreateInstance()
    {
        return WindowSingletonBase<ParentWindow>.GetInstance();
    }
    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        // 釋放單例實例并關閉所有子窗口
        WindowSingletonBase<ParentWindow>.ReleaseInstance();
        WindowSingletonBase<ParentWindow>.CloseAllChildren();
    }

    private void OpenChildWindow(object sender, RoutedEventArgs e)
    {
        // 獲取子窗口實例并顯示
        var childWindow = ChildWindow.CreateInstance();
        WindowSingletonBase<ParentWindow>.AddChildWindow(childWindow);
        WindowSingletonBase<ChildWindow>.ShowOrActivate();
    }
}

ChildWindow.cs

public partial class ChildWindow : Window
{
    static ChildWindow()
    {
        // 注冊無參構(gòu)造函數(shù)(方式1)
        // WindowSingletonBase<ChildWindow>.RegisterConstructor(args => new ChildWindow());
        // 注冊無參構(gòu)造函數(shù)(方式2)
         WindowSingletonBase<ChildWindow>.RegisterConstructor(delegate (object[] args)
         {
             return new ChildWindow();
         });
    }

    public ChildWindow()
    {
        InitializeComponent();
    }
    
    /// <summary>
    /// 聲明單例窗口
    /// </summary>
    public static ChildWindow CreateInstance()
    {
        return WindowSingletonBase<ChildWindow>.GetInstance();
    }
    /// <summary>
    /// 關閉窗口
    /// </summary>
    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        // 從父窗體的子窗口列表中移除
        WindowSingletonBase<ParentWindow>.RemoveChild(this);
        WindowSingletonBase<ChildWindow>.ReleaseInstance();
    }
}

2.2 有參構(gòu)造窗體-使用單例窗體

ParentWindow.cs

public partial class ParentWindow : Window
{
    static ParentWindow()
    {
        // 注冊無參構(gòu)造函數(shù)
        WindowSingletonBase<ParentWindow>.RegisterConstructor(args => new ParentWindow());
    }

    public ParentWindow()
    {
        InitializeComponent();
    }
    /// <summary>
    /// 聲明單例窗口 Instance
    /// </summary>
    public static ParentWindow CreateInstance()
    {
        return WindowSingletonBase<ParentWindow>.GetInstance();
    }
    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        // 釋放單例實例并關閉所有子窗口
        WindowSingletonBase<ParentWindow>.ReleaseInstance();
        WindowSingletonBase<ParentWindow>.CloseAllChildren();
    }

    private void OpenChildWindow(object sender, RoutedEventArgs e)
    {
        // 獲取子窗口實例并顯示
        var childWindow = ChildWindow.CreateInstance("張三", 18);
        WindowSingletonBase<ParentWindow>.AddChildWindow(childWindow);
        WindowSingletonBase<ChildWindow>.ShowOrActivate();
    }
}

ChildWindow.cs

public partial class ChildWindow : Window
{
    static ChildWindow()
    {
        // 注冊無參構(gòu)造函數(shù)
        WindowSingletonBase<ChildWindow>.RegisterConstructor(delegate (object[] args)
        {
            return new AddGroupWin(args[0] as string, (int)args[1]);
        });
    }

    public ChildWindow(string name, int age)
    {
        InitializeComponent();
    }
    
    /// <summary>
    /// 聲明單例窗口
    /// </summary>
    public static ChildWindow CreateInstance(string name, int age)
    {
        return WindowSingletonBase<ChildWindow>.GetInstance(name, age);
    }
    /// <summary>
    /// 關閉窗口
    /// </summary>
    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        // 從父窗體的子窗口列表中移除
        WindowSingletonBase<ParentWindow>.RemoveChild(this);
        WindowSingletonBase<ChildWindow>.ReleaseInstance();
    }
}

2.3 有參構(gòu)造窗體-窗體刷新

如果這個彈窗是在列表中,點擊編輯按鈕彈窗,我們需要每次點擊的時候都刷新窗口??梢栽贑reateInstance方法中做一些改變。

ParentWindow.cs

public partial class ParentWindow : Window
{
    static ParentWindow()
    {
        // 注冊無參構(gòu)造函數(shù)
        WindowSingletonBase<ParentWindow>.RegisterConstructor(args => new ParentWindow());
    }

    public ParentWindow()
    {
        InitializeComponent();
    }
    /// <summary>
    /// 聲明單例窗口 Instance
    /// </summary>
    public static ParentWindow CreateInstance()
    {
        return WindowSingletonBase<ParentWindow>.GetInstance();
    }
    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        // 釋放單例實例并關閉所有子窗口
        WindowSingletonBase<ParentWindow>.ReleaseInstance();
        WindowSingletonBase<ParentWindow>.CloseAllChildren();
    }

    private void OpenChildWindow(object sender, RoutedEventArgs e)
    {
        // 獲取子窗口實例并顯示
        var childWindow = ChildWindow.CreateInstance("張三", 18);
        WindowSingletonBase<ParentWindow>.AddChildWindow(childWindow);
        WindowSingletonBase<ChildWindow>.ShowOrActivate();
    }
}

ChildWindow.cs

public partial class ChildWindow : Window
{
    // 演示需要(不推薦在ChildWindow中聲明viewModel)
    private ChildWindowViewModel viewModel;
    private static ChildWindow _childWindow;
    static ChildWindow()
    {
        // 注冊無參構(gòu)造函數(shù)
        WindowSingletonBase<ChildWindow>.RegisterConstructor(delegate (object[] args)
        {
            return new AddGroupWin(args[0] as string, (int)args[1]);
        });
    }

    public ChildWindow(string name, int age)
    {
        InitializeComponent();
    }
    
    /// <summary>
    /// 聲明單例窗口
    /// </summary>
    public static ChildWindow CreateInstance(string name, int age)
    {
        if (_childWindow!=null) 
        {
            ChildWindowWinViewModel model = _childWindow.viewModel as ChildWindowWinViewModel;
            // 點擊的是當前展示的數(shù)據(jù),則返回當前window
            if (model != null && model.name == name && model.age == age)
            {
                return _childWindow;
            }
            else 
            {
                // 點擊的是另一條數(shù)據(jù),則重新new viewModel,重新設置 _childWindow的DataContext
                // 在這里省略ChildWindowWinViewModel代碼,根據(jù)情況自行編寫
                _childWindow.viewModel = new  ChildWindowWinViewModel(id, instId, _childWindow);
                _childWindow.DataContext = _childWindow.viewModel;
                return _childWindow;
            }
        }
        // 如果 _childWindow 是空的,則聲明單例窗口。
        _childWindow = WindowSingletonBase<ChildWindow>.GetInstance(name, age);
        return _childWindow;
    }
    /// <summary>
    /// 關閉窗口
    /// </summary>
    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        // 從父窗體的子窗口列表中移除
        WindowSingletonBase<ParentWindow>.RemoveChild(this);
        WindowSingletonBase<ChildWindow>.ReleaseInstance();
    }
}

以上就是WPF中實現(xiàn)單例窗口的解決方案的詳細內(nèi)容,更多關于WPF單例窗口的資料請關注腳本之家其它相關文章!

相關文章

  • C# Dynamic關鍵字之:dynamic為什么比反射快的詳解

    C# Dynamic關鍵字之:dynamic為什么比反射快的詳解

    本篇文章是對C#中dynamic為什么比反射快進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C#刪除Excel中的圖片實例代碼

    C#刪除Excel中的圖片實例代碼

    在本篇文章里小編給大家分享了關于C#刪除Excel中的圖片的實例代碼內(nèi)容,有興趣的朋友們參考學習下。
    2019-07-07
  • C#?wpf?無邊框窗口添加陰影效果的實現(xiàn)

    C#?wpf?無邊框窗口添加陰影效果的實現(xiàn)

    在本篇內(nèi)容中小編給大家整理了一篇關于C#?wpf?無邊框窗口添加陰影效果的具體方法內(nèi)容,有興趣的朋友們可以學習參考下
    2022-11-11
  • C#實現(xiàn)洗牌算法

    C#實現(xiàn)洗牌算法

    洗牌算法的要求是這樣的:將N個數(shù)亂序后輸出.由于和撲克牌的洗牌過程比較相似所以我也就稱為洗牌算法了.很多地方都不自覺的需要這個算法的支持.也可以將這個算法擴展為從N個數(shù)中取出M個不重復的數(shù)(0<M<=N).今天我們看下如何用C#來實現(xiàn)
    2015-03-03
  • 解決C# X64應用程序中讀取WParam溢出的問題

    解決C# X64應用程序中讀取WParam溢出的問題

    C#應用程序是AnyCPU的,在一段處理鼠標滾輪WM_MOUSEWHEEL的代碼里碰到溢出的問題OverflowException
    2013-04-04
  • C#實現(xiàn)TFTP客戶端的項目實踐

    C#實現(xiàn)TFTP客戶端的項目實踐

    TFTP不僅有斷點續(xù)傳,多用戶級別限制等功能,本文主要介紹了C#實現(xiàn)TFTP客戶端的項目實踐,具有一定的參考價值,感興趣的可以了解一下
    2024-04-04
  • C#編程實現(xiàn)QQ界面的方法

    C#編程實現(xiàn)QQ界面的方法

    這篇文章主要介紹了C#編程實現(xiàn)QQ界面的方法,較為詳細的分析了C#實現(xiàn)模擬QQ登錄界面的具體步驟與相關實現(xiàn)代碼,需要的朋友可以參考下
    2016-03-03
  • WPF自定義路由事件的實例教程

    WPF自定義路由事件的實例教程

    &#65279;WPF中有兩種事件模型,一種是在WinForm時代就存在的CLR事件,另一種是WPF時代的路由事件,這篇文章主要給大家介紹了關于WPF自定義路由事件的相關資料,需要的朋友可以參考下
    2021-09-09
  • C# 實現(xiàn)顏色的梯度漸變案例

    C# 實現(xiàn)顏色的梯度漸變案例

    這篇文章主要介紹了C# 實現(xiàn)顏色的梯度漸變案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • C# OpenCVSharp實現(xiàn)顏色空間轉(zhuǎn)換功能

    C# OpenCVSharp實現(xiàn)顏色空間轉(zhuǎn)換功能

    OpenCVSharp 是 OpenCV 的 C# 封裝,允許開發(fā)者在 .NET 環(huán)境下使用 OpenCV 提供的強大計算機視覺和圖像處理功能,它支持大多數(shù) OpenCV 的功能,包括圖像讀取、處理、特征檢測、機器學習等,所以本文給大家介紹了C# OpenCVSharp實現(xiàn)顏色空間轉(zhuǎn)換功能,需要的朋友可以參考下
    2025-09-09

最新評論

泽州县| 阿拉善右旗| 禹州市| 平凉市| 大丰市| 永登县| 若尔盖县| 敦化市| 元朗区| 华安县| 即墨市| 右玉县| 玛沁县| 临朐县| 黄浦区| 闸北区| 丹阳市| 唐海县| 新竹市| 大邑县| 铜鼓县| 铁力市| 无锡市| 静宁县| 周口市| 浙江省| 巍山| 专栏| 塔城市| 应用必备| 马尔康县| 上杭县| 武邑县| 敦煌市| 珲春市| 昆明市| 巩义市| 苏州市| 丰顺县| 星子县| 图木舒克市|