繁体   English   中英

在 WPF 中处理 Window 实例的“正确”方法是什么

[英]What is the “correct” way of handling Window instances in WPF

在创建 WPF 应用程序并使用 Window class 时,我创建了自己的处理 ZC89686A387D52B12B5B3C72 实例的模式。 如果我只需要一个 Window 实例,我的方法是:

private CustomWindow CustomWindow;
private void MenuItemCustomWindowOpenClicked(object sender, RoutedEventArgs e)
{
    if (CustomWindow == null)
        {
            CustomWindow = new CustomWindow();
            CustomWindow.Closed += delegate
            {
                CustomWindow = null;
            };
            CustomWindow.Show();
        }
    }

CustomWindow 是继承 Window class 的 class。

我想知道是否有更好的方法? 如果我想保留实例而不创建新实例,我应该使用什么? 我可以重复使用已经关闭的 window 吗?

这似乎很好。 要重新使用 window,您必须处理Closing事件并取消它,然后Hide window 而不是关闭它。 要再次打开它,您可以再次调用Show

如果您的要求 state 出于某种原因需要重新使用您的 Windows,我的建议是不要这样做。 你的可能会更加干净和可读。

如果您需要这样做,我的 2 美分是实现一种IWindowsManager注入注入到任何需要使用 Windows 的Windows

可能是一个很好的起点。

窗口管理器

interface IWindowsManager : IDisposable
{
    Window GetWindow<T>() where T : Window;

    void ShowWindow<T>() where T : Window;

    void CloseWindow<T>() where T : Window;
}

窗口管理器

class WindowsManager : IWindowsManager
{
    private Dictionary<Type, Window> windows;
    private bool disposed;

    public WindowsManager()
    {
        this.windows = new Dictionary<Type, Window>();
        this.disposed = false;
    }

    public Window GetWindow<T>() where T : Window
    {
        if (this.windows.ContainsKey(typeof(T)))
            return this.windows[typeof(T)];

        var w = Activator.CreateInstance(typeof(T)) as Window;
        if (w == null)
            throw new InvalidCastException($"The passed Type {typeof(T)} does not extend Window class.");
        w.Closing += W_Closing;

        this.windows.Add(typeof(T), w);
        return w;
    }

    private void W_Closing(object sender, CancelEventArgs e)
    {
        e.Cancel = true;
        Window w = sender as Window;
        w.Hide();
    }

    public void ShowWindow<T>() where T : Window
    {
        Window w = null;

        if (!this.windows.ContainsKey(typeof(T)))
            w = this.GetWindow<T>();

        w = this.windows[typeof(T)];

        w.Show();
    }

    public void CloseWindow<T>() where T : Window
    {
        if (!this.windows.ContainsKey(typeof(T)))
            throw new InvalidEnumArgumentException($"Failed to get existing Window of Type {typeof(T)}");

        var w = this.windows[typeof(T)];

        w.Hide();
    }

    public void Dispose()
    {
        Dispose(true);

        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                foreach (var window in this.windows)
                {
                    var w = window.Value;
                    w.Close();
                    w.Closing -= W_Closing;
                }
            }

            this.disposed = true;
        }
    }
}

WindowsManager实现IDisposable接口,在处理时关闭 windows。 可以根据您的要求实现任何其他逻辑。

为了让代码正常工作,您必须在显示或关闭Window时使用WindowsManager实例,并且不要直接调用WindowXXX.Show()WindowXXX.Close()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM