• 简单管理WPF及Winform所有弹出窗体


    在贴吧上看到这么个需求,就是需要能够关闭最后一个处于激活状态的窗体

    所以写了这么个小类

    /// <summary>
        /// 窗体管理
        /// </summary>
        public class WindowManager
        {
            private static Lazy<WindowManager> manager = new Lazy<WindowManager>(() => new WindowManager());
            public static WindowManager Manager
            {
                get
                {
                    return manager.Value;
                }
            }
    
            /// <summary>
            /// 存储所有加入的激活窗体
            /// </summary>
            private List<Window> lastWindows = new List<Window>();
    
            /// <summary>
            /// 将窗体添加到管理中
            /// </summary>
            /// <param name="window">要添加的窗体</param>
            public void AddActive(Window window)
            {
                //绑定窗体的激活事件
                window.Activated += Window_Activated;
                //绑定窗体的关闭事件
                window.Closing += Window_Closing;
    
                //如果添加的新窗体已加载,则添加到激活列表中
                if (window.IsLoaded)
                    this.lastWindows.Add(window);
            }
    
            private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
            {
                this.RemoveActive(sender);
            }
    
            private Window RemoveActive(object sender)
            {
                var window = sender as Window;
    
                //关闭,则从队列中移除
                if (this.lastWindows.Contains(window))
                {
                    this.lastWindows.Remove(window);
                }
                return window;
            }
    
            private void Window_Activated(object sender, EventArgs e)
            {
                var window = this.RemoveActive(sender);
                this.lastWindows.Add(window);
            }
    
            /// <summary>
            /// 关闭最后一个激活的窗体
            /// </summary>
            public void CloseActive()
            {
                //获取最后一个,直接关闭
                var window = this.lastWindows.LastOrDefault();
                if (window != null)
                {
                    window.Close();
                }
            }
    
            /// <summary>
            /// 获取最后一个激活的窗体
            /// </summary>
            /// <returns></returns>
            public Window GetLastActive()
            {
                return this.lastWindows.LastOrDefault();
            }
    
            /// <summary>
            /// 关闭所有已激活的窗体
            /// </summary>
            public void CloseAll()
            {
                for (int i = this.lastWindows.Count - 1; i > -1; i--)
                {
                    this.lastWindows[i].Close();
                }
            }
        }
    

      

    使用方式

    Xaml

      <StackPanel>
            <Button Content="Open" Click="Open_Click"/>
            <Button Content="Get" Click="Get_Click"/>
            <Button Content="Close" Click="Close_Click"/>
            <Button Content="Close All" Click="CloseAll_Click"/>
    
            <TextBox x:Name="txt"
                     TextWrapping="Wrap" Height="300" VerticalScrollBarVisibility="Auto" />
    
        </StackPanel>
    

      后台事件

      private void Open_Click(object sender, RoutedEventArgs e)
            {
               var window= new Window1(Guid.NewGuid().ToString());
                WindowManager.Manager.AddActive(window);
                window.Show();
            }
    
            private void Get_Click(object sender, RoutedEventArgs e)
            {
                var window = WindowManager.Manager.GetLastActive();
                if (window != null)
                    this.txt.Text += window.Title + " :Active" + Environment.NewLine;
            }
    
            private void Close_Click(object sender, RoutedEventArgs e)
            {
                WindowManager.Manager.CloseActive();
            }
    
            private void CloseAll_Click(object sender, RoutedEventArgs e)
            {
                WindowManager.Manager.CloseAll();
            }
    

      开启新窗体时,以其Title来标识不同的窗体

    /// <summary>
        /// Window1.xaml 的交互逻辑
        /// </summary>
        public partial class Window1 : Window
        {
            public Window1(string title)
            {
                InitializeComponent();
                this.Title = title;
            }
    
        }
    

      最后效果gif

    ========================再次更新======================

    再次更新后,也可以用于Winform程序

    更新后的代码如下

     /// <summary>
        /// 窗体管理
        /// </summary>
        public class WindowManager<T> where T : class
        {
            private static Lazy<WindowManager<T>> manager = new Lazy<WindowManager<T>>(() => new WindowManager<T>());
    
            /// <summary>
            /// 管理类实例
            /// </summary>
            public static WindowManager<T> Manager
            {
                get
                {
                    return manager.Value;
                }
            }
    
            private WindowManager()
            {
    
            }
    
            /// <summary>
            /// 存储所有加入的激活窗体
            /// </summary>
            private List<WindowEx<T>> lastWindows = new List<WindowEx<T>>();
    
            /// <summary>
            /// 将窗体添加到管理中
            /// </summary>
            /// <param name="window">要添加的窗体</param>
            public void AddActive(T window)
            {
                var w = new WindowEx<T>(window);
                w.Actived += W_Actived;
                w.Closeing += W_Closeing;
            }
    
            private void W_Closeing(WindowEx<T> obj)
            {
                //关闭,则从队列中移除
                if (this.lastWindows.Contains(obj))
                {
                    this.lastWindows.Remove(obj);
                }
            }
    
            private void W_Actived(WindowEx<T> obj)
            {
                //关闭,则从队列中移除
                if (this.lastWindows.Contains(obj))
                {
                    this.lastWindows.Remove(obj);
                }
                this.lastWindows.Add(obj);
            }
    
            /// <summary>
            /// 关闭最后一个激活的窗体
            /// </summary>
            public void CloseActive()
            {
                //获取最后一个,直接关闭
                var window = this.lastWindows.LastOrDefault();
                if (window != null)
                {
                    window.Close();
                }
            }
    
    
            /// <summary>
            /// 获取最后一个激活的窗体
            /// </summary>
            public T ActiveWindow
            {
                get
                {
                    var last = this.lastWindows.LastOrDefault();
                    if (last != null)
                        return last.Item;
                    return null;
                }
            }
    
            /// <summary>
            /// 关闭所有已激活的窗体
            /// </summary>
            public void CloseAll()
            {
                for (int i = this.lastWindows.Count - 1; i > -1; i--)
                {
                    this.lastWindows[i].Close();
                }
            }
        }
    

      

    /// <summary>
        /// Window
        /// </summary>
        /// <typeparam name="T"></typeparam>
        internal class WindowEx<T> where T : class
        {
            public event Action<WindowEx<T>> Actived;
            public event Action<WindowEx<T>> Closeing;
            public T Item { get; set; }
            public WindowEx(T item)
            {
                this.Item = item;
                //如果是Form的话
                if (typeof(T) == typeof(Form))
                {
                    var f = (this.Item as Form);
                    f.Activated += F_Activated;
                    f.FormClosing += F_FormClosing;
                }
                else if (typeof(T) == typeof(Window))
                {
                    var w = this.Item as Window;
                    w.Activated += W_Activated;
                    w.Closing += W_Closing;
                }
            }
    
            private void W_Closing(object sender, System.ComponentModel.CancelEventArgs e)
            {
                this.Closeing?.Invoke(this);
            }
    
            private void W_Activated(object sender, EventArgs e)
            {
                this.Actived?.Invoke(this);
            }
    
            private void F_FormClosing(object sender, FormClosingEventArgs e)
            {
                this.Closeing?.Invoke(this);
            }
    
            private void F_Activated(object sender, EventArgs e)
            {
                this.Actived?.Invoke(this);
            }
    
            public void Close()
            {
                this.Item.GetType().GetMethod("Close").Invoke(this.Item, null);
            }
    
            public override bool Equals(object obj)
            {
                if (obj is WindowEx<T> item)
                {
                    return item.Item.Equals(this.Item);
                }
                return base.Equals(obj);
            }
    
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
        }
    

      

    使用方式更新,示例为winform

      private void openToolStripMenuItem_Click(object sender, EventArgs e)
            {
                var window = new Form2(Guid.NewGuid().ToString());
                WindowManager<Form>.Manager.AddActive(window);
                window.Show();
            }
    
            private void getToolStripMenuItem_Click(object sender, EventArgs e)
            {
                var window = WindowManager<Form>.Manager.ActiveWindow;
                if (window != null)
                    this.richTextBox1.Text+= window.Text + " :Active" + Environment.NewLine;
            }
    
            private void closeToolStripMenuItem_Click(object sender, EventArgs e)
            {
                WindowManager<Form>.Manager.CloseActive();
            }
    
            private void closeAllToolStripMenuItem_Click(object sender, EventArgs e)
            {
                WindowManager<Form>.Manager.CloseAll();
            }
    

      

  • 相关阅读:
    docker cacti
    zabbix5.0官方部署+监控nginx+mysql
    CentOS7 Haproxy2.2.2部署示例
    LVS(DR) + keepalived
    linux备份整个系统
    docker部署OceanBase 试用版
    NextCloud开源视频会议平台
    idea使用maven proguard 对ssm项目进行代码混合详细步骤
    C# 范围运算符[1..2]
    对象是否为空的扩展方法
  • 原文地址:https://www.cnblogs.com/rbzz/p/15189006.html
Copyright © 2020-2023  润新知