• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > 如何搭建新的WPF项目框架

如何搭建新的WPF项目框架

作者:New丶Power 字体:[增加 减小] 来源:互联网 时间:2017-05-28

New丶Power 通过本文主要向大家介绍了wpf mvvm框架搭建,wpf mvvm框架,wpf ui框架,wpf开发框架,wpf界面框架等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

下面就WPF项目框架搭建步骤一步一步的分享给大家。

在WPF项目开发中最常用的开发模式无疑是MVVM模式,  MVVM模式开发的好处,在这里就不详细讨论, 还有 本文中所使用MVVMLight框架,为什么使用MVVM框架(1、框架较轻,2、学习成本低、3、适用大多数中小型项目,4、相对于微软的prism框架更容易上手)   
下面开始 一步一步 搭建框架

第一步: 利用反射创建VM构造器

 

public class ViewModelFactory
{
 private static Dictionary<string, object> vmMap = new Dictionary<string, object>();<br>
 public static T GetViewModel<T>() where T : ViewModelBase
 {
  Type vmType = typeof(T);
  if (vmMap.ContainsKey(vmType.FullName))
  {
   return (T)vmMap[vmType.FullName];
  }
  else
  {
   object vm = Activator.CreateInstance(vmType);
   vmMap.Add(vmType.FullName, vm);
   return (T)vm;
  }
 }

 public static T GetViewModel<T>(object[] data,string id) where T : ViewModelBase
 {
  Type vmType = typeof(T);
  if (vmMap.ContainsKey(id))
  {
   return (T)vmMap[id];
  }
  else
  {
   object vm = Activator.CreateInstance(vmType, data);
   vmMap.Add(id, vm);
   return (T)vm;
  }
 }
}

</div>

为什么用一个Dictionary  将ViewModel  缓存起来,相信利用MVVM模式开发大多数的开发者碰到的问题无疑是各个VM之间的数据通信问题,利用Dictionary缓存起来有两个好处:

1、可以解决VM之间相互通信的问题(当然你也可以用MvvmLight的 Message机制来通信,PS:个人认为完全没必要用MvvmLight中的 Messgae,如果我们框架搭的合理完全可以规避去用MvvmLight中 Message,Message比较难于管理,如果在我们的代码中出现大量的Message无疑是一件痛苦的事情,所以笔者不推荐用MvvmLight中的Message)

2、如果我们的应用程序要频繁的与服务器做交互,我们完全可以用缓存,以避免每次都去请求服务器(可以缓存一些在应用程序中一直使用的数据,规避二次请求)

public static T GetViewModel<T>() where T : ViewModelBase  这个函数(将我们的VM完全限定名作为KEY缓存)适用于单例模式的VM,

public static T GetViewModel<T>(object[] data,string id) where T : ViewModelBase 这个函数(主要构件带参数的VM构造函数,id是唯一ID),为什么会用到它,举个例子

例如我们的QQ聊天窗口,所有聊天窗口基本相同用到的VM类型也是相同,所以这时候就需要多个VM实例了,第一种方法就行不通了 所以会用到这种方法去构建VM,并将id作为KEY值缓存起来

第二步:构建我们的ViewModel 基类:

public delegate void CloseEventHandle(object sender);
 public class CustomViewModel : ViewModelBase
 {

  public event CloseEventHandle CloseEvent;
 protected bool hasData;

  public CustomViewModel()
  {
  LoadCommand = new RelayCommand(() =>
   {
    if (!hasData)
    {

     ThreadPool.QueueUserWorkItem((obj) =>
     {
      lock (this)
      {
       OnLoad();
       hasData = true;
      }
     });
    }
   });
  }public RelayCommand LoadCommand { private set; get; }

  protected virtual void OnLoad()
  {

  }

  protected void OnClose(object sender)
  {
   if (sender != null && CloseEvent != null)
   {
    CloseEvent(sender);
   }
  }
 }

</div>

上面CustomViewModel 继承的ViewModelBase 是MvvmLight中的ViewModelBase,至于MvvmLight用法不在本文中讨论,

1、为什么要声明LoadCommand,因为大多数的时候我们会在窗体或用户控件Loaded的时候去加载数据,有可能是异步加载,也有可能是同步加载,所以我们在CustomViewModel中

声明省去了各个VM子类中去声明LoadCommand的麻烦,使用时我们直接在XAML利用MvvmLight提供的EventToCommand 去绑定LoadCommand,然后在对应的VM去重写CustomViewModel基类中的OnLoad方法就可以了。

2、CloseEvent 故名思议是用来在VM中关闭窗体用的(详细用法会在下文中讨论)

3、我们也可以将一些公有的数据都提炼到VM中来。

第三步  管理窗口:

  在开发程序的时候我们通常要去管理窗口的如果你没用到MVVM模式 或者是传统的Winform 你可以随便的去new Window(),或者随便的去改Window的构造函数,或者随意的去构造单例窗体,但是如果用到了MVVM模式似乎以上所说的一切都变得复杂了,刚开始的时候我也是挺伤脑筋的,后来在不断的重构代码中找到了解决方法,(PS:本人也是一名菜鸟,只想把自己在开发中的问题及解决方法分享出来,未必就是好的解决方案,所以大神们勿喷)下面上代码: 构建我们的ShowHelper类:


public class ShowHelper
 {
  private static Dictionary<string, Window> windowManager = new Dictionary<string, Window>();

  public static void ShowDiaglogUc<T>(string title, object[] constructors = null, bool isDialog = false) where T : UserControl
  {
   Type controlType = typeof(T);
   string key;

   if (constructors == null) //如果构造参数为null
   {
    key = controlType.FullName; //key = T 的完全限定名
   }
   else
   {
    // 如果不为空 并且 第二个构造参数为string(第二个参数代表id -->有可能是GroupId 有可能是UserId);
    if (constructors.Length == 2 && constructors[1] is string) //ps:这里本人写死了可以根据需求自行修改
    {
     key = controlType.FullName + constructors[1].ToString(); //key = 控件 完全限定名+id;
    }
    else //不满足条件
    {
     key = controlType.FullName; //key = 限定名
    }

   }

   if (windowManager.ContainsKey(key)) //如果包含KEY
   {
    windowManager[key].Topmost = true; //设置TopMost
    return;
   }

   UserControl content;
   if (constructors == null)
   {
    content = Activator.CreateInstance(controlType) as UserControl;
   }
   else
   {
    content = Activator.CreateInstance(controlType, constructors) as UserControl;
   }

   BaseWindow window = new BaseWindow(); //PS这是自己封装 的Window,(可以用直接用原始的Wpf Widnow)
   window.Title = title;
   windowManager.Add(key, window);
   window.Closed += (sen, cloE) =>
   {
    windowManager.Remove(key);
   };
   if (isDialog)
   {
    window.ShowDialog();
   }
   else
   {
    window.Show();
   }
   #region 注册关闭事件
   if (content.DataContext as CustomViewModel != null)
   {
    CustomViewModel vm = content.DataContext as CustomViewModel;
    vm.CloseEvent += (obj) =>
    {
     if (content.DataContext.Equals(obj))
     {
      window.Close();
     }
    };
   }
   #endregion
  }


  public static CustomDialogResult ShowOkCancleUC<T>(string title, MsgBoxBtn okCancle, out object data) where T : Control
  {
   Type vmType = typeof(T);
   Control content = Activator.CreateInstance(vmType) as Control;
   OkCanleWindow window = new OkCanleWindow();
   window.ShowInTaskbar = false;
   return window.ShowDialog(title, okCancle, content, out data);
  }

  public static CustomDialogResult MessageBoxDialog(string title, string message, MsgBoxBtn okCancle)
  {
   OkCanleWindow window = new OkCanleWindow();
   window.ShowInTaskbar = false;
   object none;
   return window.ShowDialog(title, okCancle, new MessageUC() { Message = message }, out none);
  }


、(1)开始剖析 public static void ShowDiaglogUc<T>(string title, object[] constructors = null, bool isDialog = false) where T : UserControl
  ShowDialogUc 是用来在VM中用来创建UserControl并显示在Window中的。你可能会问为啥用windowManager 将窗口缓存起来(PS这里主要还是为了解决单例窗口的麻烦),

  至于 下面这段代码,我们可以回到创建的CustomerViewModel中,对这里需要注册VM中CloseEvent事件,这样我们在VM中就可以直接调用OnClose()方法就OK了

  #region 注册关闭事件
   if (content.DataContext as CustomViewModel != null)
   {
    CustomViewModel vm = content.DataContext as CustomViewModel;
    vm.CloseEvent += (obj) =>
    {
     if (content.DataContext.Equals(obj))
     {
      window.Close();
     }
    };
   }
  #region 注册关闭事件

</div>

(2)开始剖析 public static void ShowDiaglogUc<T>(string title, object[] constructors = null, bool isDialog = false) where T : UserControl 函数中的 constructors 参

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • WPF MVVM制作发送短信小按钮
  • WPF MVVM示例讲解
  • 如何搭建新的WPF项目框架

相关文章

  • 2017-05-28详解C#编程中一维数组与多维数组的使用
  • 2017-05-28C# 基础入门--常量
  • 2017-05-28C#正则函数用法实例【匹配、替换、提取】
  • 2017-05-28C#简单读取、改变文件的创建、修改及访问时间的方法
  • 2017-05-28在.NET中读取嵌入和使用资源文件的方法
  • 2017-05-28C#获得文件属性信息的实现方法
  • 2017-05-28Winform窗体传值的方法(示例)
  • 2017-05-28使用C# Winform应用程序获取网页源文件的解决方法
  • 2017-05-28轻松学习C#的哈希表
  • 2017-05-28浅析C# 使用Process调用外部程序中所遇到的参数问题

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • c#字符串值类型与引用类型比较示例
    • 学习Winform文本类控件(Label、Button、TextBox)
    • C#常见算法面试题小结
    • c#远程html数据抓取实例分享
    • C# VB 实现10进制 16进制之间互相转换
    • C#中使用@声明变量示例(逐字标识符)
    • C#之WinForm跨线程访问控件实例
    • C#实现文件上传以及多文件上传功能
    • 分享我在工作中遇到的多线程下导致RCW无法释放的问题
    • C#实现毫秒转换成时分秒的方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有