首页 > 其他分享 >【WPF】-MVVM-封装窗口管理器解耦在ViewModel中弹出窗口

【WPF】-MVVM-封装窗口管理器解耦在ViewModel中弹出窗口

时间:2023-05-07 13:22:06浏览次数:33  
标签:管理器 name MVVM ViewModel new 窗口 public View

一.在ViewModel层直接调用View弹出窗体

如下图所示,这样做就发生了在ViewModel层直接使用了View,两者产生了耦合,ViewModel里是不应该包含View的,这不是我们期望的。

 

二.封装窗口管理器解耦在ViewModel中调用View

2.1.封装窗口管理器

延迟了对象的创建,先把类型(对象的模板)注册进来,当你什么真正需要的时候,容器再使用类型把创建对象出来

 1  /// <summary>
 2     /// 窗口管理器
 3     /// </summary>
 4     public class WindowManager
 5     {
 6         static Dictionary<string, WindowStruct> _regWindowContainer = new Dictionary<string, WindowStruct>();
 7 
 8         /// <summary>
 9         /// 注册类型
10         /// </summary>
11         /// <typeparam name="T"></typeparam>
12         /// <param name="name"></param>
13         /// <param name="owner"></param>
14         public static void Register<T>(string name, System.Windows.Window owner = null)
15         {
16             if (!_regWindowContainer.ContainsKey(name))
17             {
18                 _regWindowContainer.Add(name, new WindowStruct { WindowType = typeof(T), Owner = owner });
19             }
20         }
21 
22         /// <summary>
23         /// 获取对象
24         /// </summary>
25         /// <typeparam name="T"></typeparam>
26         /// <param name="name"></param>
27         /// <param name="dataContext"></param>
28         /// <returns></returns>
29         public static bool ShowDialog<T>(string name, T dataContext)
30         {
31             if (_regWindowContainer.ContainsKey(name))
32             {
33                 Type type = _regWindowContainer[name].WindowType;
34                 //反射创建窗体对象
35                 var window = (System.Windows.Window)Activator.CreateInstance(type);
36                 window.Owner = _regWindowContainer[name].Owner;
37                 window.DataContext = dataContext;
38                 return window.ShowDialog() == true;
39             }
40 
41             return false;
42         }
43     }
44 
45     public class WindowStruct
46     {
47         public Type WindowType { get; set; }
48         public System.Windows.Window Owner { get; set; }
49     }

 

2.2.在主界面注册要弹出的窗口类型

这里可以使用PopupWindow,因为同属于View层。

 

 1  /// <summary>
 2     /// DialogMainWindow.xaml 的交互逻辑
 3     /// </summary>
 4     public partial class DialogMainWindow : Window
 5     {
 6         public DialogMainWindow()
 7         {
 8             InitializeComponent();
 9             //注册窗体类型到容器
10             //通过第三方窗口容器View和ViewModel解耦
11             WindowManager.Register<PopupWindow>("PopupWindow", this);
12             this.DataContext = new PopupWindowViewModel();
13         }
14     }

 

2.3.使用窗口管理器,在ViewModel层弹出窗体,达到解耦的目的

 1 public class PopupWindowViewModel: CommandBase
 2     {
 3         public CommandBase BtnShowDialogCommand { get; set; }
 4 
 5 
 6         public PopupWindowViewModel()
 7         {
 8             BtnShowDialogCommand = new CommandBase()
 9             {
10                 DoExecute = new Action<object>((obj) => {
11                     //直接在ViewModel层调用View层,产生了耦合
12                     //PopupWindow popupWindow = new PopupWindow();
13                     //popupWindow.ShowDialog();
14 
15                    
16                     PopupModel<string> popupModel = new PopupModel<string>();
17                     popupModel.Value = obj.ToString();
18 
19                     //经过这样的封装,解耦了在ViewModel层直接使用View
20                     WindowManager.ShowDialog<PopupModel<string>>("PopupWindow", popupModel);
21                 }),
22                 DoCanExecute = new Func<object, bool>((obj) => {
23                     return true;
24                 })
25             };
26         }
27     }

 

经过这样的封装,解耦了在ViewModel层直接使用View。
总结:延迟了对象的创建,先把类型(对象的模板)注册进来,当你什么真正需要的时候,容器再使用类型把创建对象出来。

 

 

标签:管理器,name,MVVM,ViewModel,new,窗口,public,View
From: https://www.cnblogs.com/menglin2010/p/17378635.html

相关文章

  • 【数据结构】单调队列专题(滑动窗口问题)
    一维滑动窗口154.滑动窗口下标从0开始,数组模拟队列#include<iostream>usingnamespacestd;constintN=1e6+10;intn,k;inta[N],q[N];intmain(){scanf("%d%d",&n,&k);for(inti=0;i<n;i++)scanf("%d",&a......
  • 在 iframe 中继承父窗口 css/js 的方法
    问题缘由iframe属于一个单独的文档(单独的网页窗口)不能直接使用父页面的资源,如css和js。如果iframe和父页面同域则可以在iframe中使用parent对象来使用父页的js对象继承css因为iframe是单独的网页窗口,所以页面一般都有head标签的。在iframe子页面的head......
  • web自动化8--多新窗口,handle
    新窗口之间的跳转有些网站打开后,点击不同的链接,会重新打开一个窗口,但是想在新页面上操作,就需要先切换窗口,那么我们就能在多个页面上灵活自如的操作了。一、什么是多窗口下面的图片就是打开了多个窗口标签的图片二、获取页面窗口的句柄  1.每一个的窗口都是有不同的属性......
  • 6-解决Tomcat服务器在DOS命令窗口中的乱码问题(控制台乱码)
    1.Tomcat乱码Tomcat刚启动时的样子,很明显乱码了2.解决Tomcat乱码将CATALINA_HOME/conf/logging.properties文件中的内容修改如下:java.util.logging.ConsoleHandler.encoding=GBK下一步修改成功,演示:......
  • css随着浏览器窗口width度变化展示数据
    这是需求这是通过css写法实现的@mediascreenand(min-width:1900px){//>=1900的设备.boxWidth{width:25%;}}@mediascreenand(min-width:1440px)and(max-width:1899px){.boxWidth{width:33%;}}@mediascreen......
  • WPF主窗口显示
    我需要完成这样的一个功能,程序在运行期间时刻检测一个值的变化,当这个值变化后,立即将主窗口进行运行,用户可以进行操作。目前做的demo是这样的,来证明这个方法的可行性。我写了一个主窗口,当这个窗口最小化五秒后,又在屏幕上可见。publicpartialclassMainWindow:Window{......
  • 解决python配置环境变量后cmd窗口无法打开并弹出Microsoft store界面
    前言在一台新的机器上安装python并正确配置环境变量后,本来打算测试一下是否安装成功,结果在cmd窗口输入python执行后,没有出现版本信息,并会弹出Microsoftstore界面。反复检查了一下,环境变量确实已经正确配置了,但还是无法执行。后经查找资料解决了该问题,在此做下记录。......
  • 模拟QQ抖动窗口
    最近闲来无事,打开了发霉的QQ,查看了一些信息与空间,在打开某个聊天窗口的时候,不经意间点到了抖动窗体按钮,突然有个小想法,Access也可以做一个类似QQ抖动的功能,原理很简单,我们只需要来改变窗口的位置,来回的移动窗口,移的快一点不就可以了嘛。先来看一下效果:第一步:建窗体具体的控件属性......
  • python+playwright 学习-60 在打开的多个标签页窗口灵活切换
    前言当页面打开了多个标签页后,如何切换到自己需要的标签页上呢?使用场景以百度首页为例,当打开多个标签页后,如何切换到自己想要的页面上操作。通过context.pages可以获取到所有的page对象,每一个page对象就代表一个标签页实例fromplaywright.sync_apiimportsync_playwrigh......
  • 解决MySQL自动弹出命令行窗口
    自从装了MySQL之后,我的电脑就会在某些时刻弹出一个黑乎乎的命令行窗口,然后立马消失。一开始还以为是电脑出了什么故障,但一直没有出现其他什么问题,就是玩游戏时弹出来有点难受。有一次我眼睛看到了一闪而过的窗口有MySQL几个字,就确定了是MySQL的原因。于是上网找解决方法,找到了一......