简单管理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(); }