wpf windowController实现全局窗口管理

public class WindowController
{
    private static readonly Lazy<WindowController> _instance = new Lazy<WindowController>(() => new WindowController());
    public static WindowController Instance => _instance.Value;

    static private ConcurrentDictionary<Type, Window> _windows = new ConcurrentDictionary<Type, Window>();

    static public void RegisterWindow<T>() where T : Window, new()
    {
        Type windowKey = typeof(T);

        if (!_windows.ContainsKey(windowKey))
        {
            T window = new T();
            _windows.TryAdd(windowKey, window);
        }
        else
        {
            throw new ArgumentException($"Window with key '{windowKey.Name}' already exists.");
        }
    }

    public static T Get<T>() where T : Window
    {
        Type windowKey = typeof(T);

        if (_windows.TryGetValue(windowKey, out Window window))
        {
            if (window is T typedWindow)
            {
                return typedWindow;
            }
            else
            {
                throw new InvalidOperationException($"Window with key '{windowKey.Name}' is not of type {typeof(T).Name}.");
            }
        }
        else
        {
            throw new ArgumentException($"Window with key '{windowKey.Name}' not found.");
        }
    }

    static public void RegisterWindow(Type windowKey, Window window)
    {
        if (!_windows.ContainsKey(windowKey))
        {
            _windows.TryAdd(windowKey, window);
        }
        else
        {
            throw new ArgumentException($"Window with key '{windowKey.Name}' already exists.");
        }
    }

    static public void UnregisterWindow<T>()
    {
        _windows.TryRemove(typeof(T), out _);
    }

    static public void RegisterWindows()
    {
        try
        {
            var tmp = Assembly.GetExecutingAssembly().GetName().Name;
        	var assembly = Assembly.LoadFrom($"./{tmp}.dll");
            var types = assembly.GetTypes();

            foreach (var type in types)
            {
                if (typeof(Window).IsAssignableFrom(type) && !type.IsAbstract)
                {
                    var windowInstance = (Window)Activator.CreateInstance(type);
                    RegisterWindow(type, windowInstance);
                }
            }
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException($"Error loading or registering windows: {ex.Message}");
        }
    }
}

上面代码定义了一个名为 WindowController 的类,主要职责是管理和控制窗口(Window)的注册、获取和注销。

1. WindowController 类的静态字段和属性

private static readonly Lazy<WindowController> _instance = new Lazy<WindowController>(() => new WindowController());
public static WindowController Instance => _instance.Value;
  • _instance 是一个 Lazy<WindowController> 类型的静态字段,它用于实现 WindowController 的单例模式。Lazy 确保 WindowController 只会在第一次访问 Instance 属性时被实例化。
  • Instance 是一个静态属性,它返回 _instance.Value,即单例实例。
static private ConcurrentDictionary<Type, Window> _windows = new ConcurrentDictionary<Type, Window>();
  • _windows 是一个静态的 ConcurrentDictionary<Type, Window>,用于存储不同类型的窗口实例。它的键是窗口的类型(Type),值是实际的窗口对象(Window)。

2. RegisterWindow<T>() 方法

static public void RegisterWindow<T>() where T : Window, new()
  • 这个泛型方法用于注册一个窗口类型 T,其中 T 必须是 Window 的子类,并且具有无参构造函数。
  • 方法首先获取窗口类型的 Type 对象,然后检查 _windows 字典中是否已经存在该类型的窗口。如果存在,则抛出 ArgumentException,表示该窗口已经注册。
  • 如果不存在,则创建该类型的窗口实例,并将其添加到 _windows 字典中。

3. Get<T>() 方法

public static T Get<T>() where T : Window
  • 这个泛型方法用于获取已经注册的窗口实例。
  • 方法首先通过 typeof(T) 获取窗口类型的 Type 对象,然后尝试从 _windows 字典中获取该类型的窗口。
  • 如果找到窗口,则检查它是否是类型 T 的实例。如果是,则返回该窗口;否则抛出 InvalidOperationException,表示类型不匹配。
  • 如果找不到窗口,则抛出 ArgumentException,表示该窗口未注册。

4. RegisterWindow(Type windowKey, Window window) 方法

static public void RegisterWindow(Type windowKey, Window window)
  • 这个方法用于注册一个指定类型的窗口实例。
  • 方法接受一个 Type 对象作为键,和一个 Window 实例作为值。
  • 如果 _windows 字典中已经存在该类型的窗口,则抛出 ArgumentException,表示该窗口已经注册。
  • 如果不存在,则将该窗口添加到 _windows 字典中。

5. UnregisterWindow<T>() 方法

static public void UnregisterWindow<T>()
  • 这个泛型方法用于注销一个指定类型的窗口。
  • 方法通过 typeof(T) 获取窗口类型的 Type 对象,然后尝试从 _windows 字典中移除该类型的窗口。
  • 如果 _windows 字典中存在该窗口,则移除它。

6. RegisterWindows() 方法

static public void RegisterWindows()
  • 这个方法用于自动注册指定程序集中的所有窗口类。
  • 方法首先尝试加载名为 ./DataParser.dll 的程序集。
  • 然后,它获取该程序集中的所有类型,并检查这些类型是否是 Window 的子类且不是抽象类。
  • 如果是,则通过 Activator.CreateInstance(type) 创建该类型的窗口实例,并调用 RegisterWindow(type, windowInstance) 方法将其注册到 _windows 字典中。
  • 如果在加载程序集或注册窗口的过程中发生异常,则抛出 InvalidOperationException,并包含异常的详细信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ou.cs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值