Management Studio是我在WinForms小项目开发过程中搭建起来的一个插件式结构的应用程序框架,因为简单灵活又容易扩展,现在将它开源供读者参考。

跑起来的效果图如下所示,具备选项卡式多文档界面,Office 2007蓝色风格,插件式结构等特性。

选项卡式多文档界面 Tab MDI

通过Infragistics Dock控件,可以很容易的实现选项卡式多文档界面。只需要在主界面的窗体设计器组件栏中拖入一个ultraTabbedMdiManager控件,设定主窗体的IsMdiContainer属性为true,剩下的工作就交由这个组件来负责。

当我们用下面的代码创建一个子窗体时,它会自动的产生一个选项卡文档,参考下面代码。

Startup frm = new Startup();
frm.MdiParent = this;
frm.Show();

从上面的代码片段中可以看到仍旧是MDI的编程风格,但产生的结果是选项卡式的界面。

插件结构 PlugIn

借助于反射机制,读取当前程序集中的类型定义,找到包含有指定特性的类型,创建它的实例,即可实现基本的插件式结构。

首先,我们给需要的窗体类增加FunctionCode特性,参考下面的代码。

[FunctionCode("DataSetReader")]
public partial class DataSetReader : FormBase
{
      public DataSetReader()
      {
          InitializeComponent();
      }

然后修改创建窗体的代码,从当前的程序集类型中搜索,找到指定特性的窗体的类型后,创建它的实例。关键的代码如下面所示。

Assembly assembly = Assembly.GetExecutingAssembly();
foreach (Type type in assembly.GetTypes())
{
     try
     {
            object[] attributes = type.GetCustomAttributes(typeof(FunctionCode), true);
            foreach (object obj in attributes)
            {
                 FunctionCode attribute = (FunctionCode)obj;
                 if (!string.IsNullOrEmpty(attribute.Value))
                 {
                     if (!_formBaseType.ContainsKey(attribute.Value))
                          _formBaseType.Add(attribute.Value, type);

                     if (formBaseType == null && attribute.Value.Equals(functionCode,StringComparison.InvariantCultureIgnoreCase))
                          formBaseType = type;
                 }

最后,我们添加一个菜单项,用于显示当前已经存在的功能编码给用户选择,菜单项的实现用XML文件定义,参考项目中嵌入的资源文件ListItem.xml。

<?xml version="1.0" encoding="utf-8" ?>
<Items>
  <Item Index="0" Text="DataSet Reader"  Tag="DataSetReader" ImageIndex="17"></Item>
  <Item Index="1" Text="Translation"  Tag="Translation" ImageIndex="32"></Item>
  <Item Index="2" Text="String Builder"  Tag="TextToStringBuilder" ImageIndex="33"></Item>
  <Item Index="3" Text="License Generator"  Tag="GenLicense" ImageIndex="7"></Item>
  <Item Index="4" Text="Query Generator"  Tag="QueryGenerator" ImageIndex="34"></Item>
  <Item Index="5" Text="Lookup Generator"  Tag="LookupGenerator" ImageIndex="35"></Item>
  <Item Index="6" Text="Report Generator"  Tag="ReportGenerator" ImageIndex="36"></Item>
  <Item Index="7" Text="Query Lookup"  Tag="QueueLookUpForm" ImageIndex="37"></Item>
  <Item Index="8" Text="Database Update"  Tag="DatabaseUpdate" ImageIndex="38"></Item>
</Items>

运行时读取嵌入的资源项,生成如下界面所示的列表视图。

双击列表视图中的项或选择项后点OK都可以打开指定的功能对应的窗体。

Office 2007 蓝色风格  Office Render

借用CodeProject上的一篇文章提供的组件,我们只需要在主界面的OnLoad方法中增加2行代码即可实现蓝色的界面风格。

 private void Form1_Load(object sender, EventArgs e)
 {
     ToolStripManager.Renderer = new ERP.Misc.Office2007Renderer();
     statusStrip.Renderer = new ERP.Misc.Office2007Renderer();

Office Render组件已经设置好了默认的颜色风格,并不需要我们去调整。程序员大多没有色彩知识,ASP.NET 组件Ext.NET也是一个蓝色风格的组件,它内置的蓝色风格很受欢迎,程序员不喜欢也没有能力去维护这个复杂的配色方案,只想拿来用就可以了。

 private static Color _c1 = Color.FromArgb(167, 167, 167);
 private static Color _c2 = Color.FromArgb(21, 66, 139);
 private static Color _c3 = Color.FromArgb(76, 83, 92);
 private static Color _c4 = Color.FromArgb(250, 250, 250);
 private static Color _c5 = Color.FromArgb(248, 248, 248);
 private static Color _c6 = Color.FromArgb(243, 243, 243);
 private static Color _r1 = Color.FromArgb(255, 255, 251);
 private static Color _r2 = Color.FromArgb(255, 249, 227);
 private static Color _r3 = Color.FromArgb(255, 242, 201);
 private static Color _r4 = Color.FromArgb(255, 248, 181);

后台线程 WorkerThreadBase

WorkerThreadBase也是CodeProject上面的一篇文章的代码。通常与界面相关的长时间的操作我们应该用BackgroundWorker组件封装起来以避免界面死锁。如果不是与界面相关的操作,我们可以用多线程,并行等方法实现,也可以用这里提到的WorkerThreadBase,它的例子代码如下所示,下面是一个复制文件的例子。

 public class CopyFileWorker : WorkerThreadBase
    {
        private static CopyInfo _copyInfo;

        public CopyFileWorker(CopyInfo copyInfo)
        {
            _copyInfo = copyInfo;
        }

        protected override void Work()
        {
            copyFiles(_copyInfo);
        }

        private void copyFiles(CopyInfo copyInfo)
        {
        //check if the user called Stop
        if (StopRequested)
        {
            Console.WriteLine("User called Stop.");
            Console.WriteLine("Terminating thread while copying directory '{0}'.", copyInfo.Source);
            return;
        }

            if (!Directory.Exists(copyInfo.Destination))
            {
                Directory.CreateDirectory(copyInfo.Destination);
            }

            Console.WriteLine("CopyFiles from '{0}' to '{1}' {2}...",   copyInfo.Source,copyInfo.Destination, copyInfo.Recursive ? "recursive" : "non-recursive");

            foreach (string file in   Directory.GetFiles(copyInfo.Source))
            {
                string destination = Path.Combine(copyInfo.Destination,Path.GetFileName(file));
                File.Copy(file, destination);
            }

            if (copyInfo.Recursive)
            {
                foreach (string directory in  Directory.GetDirectories(copyInfo.Source))
                {
                    string destination = Path.Combine(copyInfo.Destination,Path.GetFileName(directory)); //get the directory name for the path
                    copyFiles(new CopyInfo(directory,destination,copyInfo.Recursive));
                }
            }
            Console.WriteLine("CopyFiles finished.");
        }

继承于WorkerThreadBase,将要操作的方法放到Work方法中重写,启动一个或多个后台线程任务的例子代码参考下面的程序片段。

DummyWorker dummyWorker = new DummyWorker();
dummyWorker.Start();

CopyFileWorker copyFileWorker = new CopyFileWorker(_copyInfo);
copyFileWorker.Start();

//wait for the two threads to finish
WorkerThreadBase.WaitAll(copyFileWorker, dummyWorker);

文本转化为.NET字符串

Management Studio的源代码包中提供几个基础的功能,比如这里的将字符串转化为.NET代码的功能。这个功能的源代码来自网友的代码,当时觉得很有用一直收藏着。

曾经有一段时间发现.NET的字符串前缀转义标识@支持换行,参考下面的代码例子,@符号支持多行文本。

private string test = @" [assembly: AssemblyCopyright(Copyright ©  2015)]
                         [assembly: AssemblyTrademark()]
                         [assembly: AssemblyCulture()]";

中文繁体简体转换

使用Microsoft.VisualBasic程序集中的方法,一步代码调用实现简体转化为繁体,参考下面的方法代码。

public string Convert(string s)
{
   return (Microsoft.VisualBasic.Strings.StrConv(s as string, Microsoft.VisualBasic.VbStrConv.TraditionalChinese, 0));
}

异常处理

凡是WinForms程序,应该在你的程度开头增加下面的几行代码以实现异常处理,将系统抛出的异常转化给当前程序处理,并提供友好的界面显示异常。

CustomExceptionHandler eh = new CustomExceptionHandler();
Application.ThreadException += new ThreadExceptionEventHandler(eh.OnThreadException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

Management Studio源代码下载:http://files.cnblogs.com/files/JamesLi2015/ManagementStudio.zip

开源WinForms界面开发框架Management Studio 选项卡文档 插件 Office 2007蓝色风格 后台线程的更多相关文章

  1. Enterprise Solution 开源项目资源汇总 Visual Studio Online 源代码托管 企业管理软件开发框架

    Enterprise Solution 是一套管理软件开发框架,在这个框架基础上开发出一套企业资源计划系统Enterprise Edition. 现将Enterprise Solution开发过程中遇 ...

  2. 开源一款私藏Management Studio插件,ProjkyAddin,送给所有使用SQLServer的园友们

    ProjkyAddin 是一款Management Studio 插件,安装包才500多kb,兼容SSMS 2005.SSMS 2008.SSMS 2008 R2.SSMS 2012.SSMS 201 ...

  3. Enterprise Solution 企业管理软件开发框架

    Enterprise Solution 开源项目资源汇总 Visual Studio Online 源代码托管 企业管理软件开发框架 Enterprise Solution 是一套管理软件开发框架,在 ...

  4. 网易云信Duilib开发实践和Windows应用界面开发框架源码开源介绍

    序言 Duilib介绍 Duilib是windows平台下的一款轻量级directUI开源库(遵循BSD协议),完全免费,可用于商业软件开发,只需在软件包里附上协议文件即可.Duilib可以简单方便地 ...

  5. 我发起了一个 .Net 开源 跨平台 GUI (界面开发框架)项目 HtmlCore

    大家好 , 我发起了一个 .Net 开源 跨平台 GUI (界面开发框架)项目 , 名字叫 HtmlCore  . 项目的一个主要目标是可以用 .Net 在 移动设备 上 开发 GUI 程序 (界面程 ...

  6. SQL Server R2 2008中的SQL Server Management Studio 阻止保存要求重新创建表的更改问题的设置方法

    在2008中会加入阻止保存要求重新创建表的更改这个选项.症状表现为修改表结构的时候会"阻止"你. SQL Server 2008“阻止保存要求重新创建表的更改”的错误的解决方案是本 ...

  7. 利用Microsoft Sql Server Management studio 创建数据库的示例

    利用Microsoft Sql Server Management studio 创建数据库的示例方法如下:   一.打开安装好的Microsoft Sql Server Management stu ...

  8. 利用SQL Server Management Studio(SSMS)复制数据库

    利用SQL Server Management Studio(SSMS)复制数据库 标签(空格分隔): SQLServer 前言 今天由于客户购买的软件版本确认了,而之前进行开发的本地数据库版本较低, ...

  9. SQL Server Management Studio 无法修改表,超时时间已到 在操作完成之前超时时

    在修改表时,保存的时候显示:无法修改表,超时时间已到 在操作完成之前超时时间已过或服务器未响应 这是执行时间设置过短的原因,可以修改一下设置便能把执行时间加长,以便有足够的时间执行完修改动作. 在 S ...

随机推荐

  1. jQuery缓存数据

    很多同学在项目中都喜欢将数据存储在HTMLElement属性上,如 1 2 3 4 <div data="some data">Test</div> < ...

  2. Hololens 手势事件执行顺序

    InteractionManager_SourcePressed (Filename: C:\buildslave\unity\build\artifacts/generated/Metro/runt ...

  3. JavaScript对象状态

    有限状态机(Finite-state machine)是一个非常有用的模型,可以模拟世界上大部分事物. 简单说,它有三个特征: * 状态总数(state)是有限的. * 任一时刻,只处在一种状态之中. ...

  4. warning C4996: 'sprintf': This function or variable may be unsafe

    选项Project   |   Configuration   Properties   |   C/C++   |   Preprocessor   |   Preprocessor   Defin ...

  5. JavaScript-Function基础知识

    function   1.  定义:一段预先设置的代码块,可以反复调用,根据输入参数的不同,返回不同的值:   2.  函数的声明方法:     (1)function 命令声明函数  functio ...

  6. Codeforces Round #361 (Div. 2) D

    D - Friends and Subsequences Description Mike and !Mike are old childhood rivals, they are opposite ...

  7. STM32之PWM君

    PWM..英语好的人估计又知道这三个大写字母代表哪三个英语单词了.小弟不才,就说中文意思好了:脉冲宽度调制,玩过飞思卡尔的人估计对PWM非常的不陌生吧.电机驱动需要PWM,控制舵机的转向需要PWM,总 ...

  8. Android Activity task 相关属性

    所谓的 task ,是指用户完成某一项任务时与之交互的一组 Activity.比如用户要向开发者汇报 bug,先打开程序主页,然后打开关于页面,再点击报告 bug 按钮,打开编辑邮件页面.当前这三个 ...

  9. BJITJobs : 北京IT圈高端职位招聘信息,成功率最高的高端求职渠道

    你有实力,但比你差的人都升了,你的师弟都年薪50万了,你还是找不到机会.为什么你离高端机会总是差一步呢?其实你离成功就差一次机会,一个适合你的高端职位的信息! 招聘网站不靠谱:三大网站都是低端职位为主 ...

  10. java-如何用eclipse打包jar

    Eclipse通过导出的方式(右键单击项目,之后选择Export)打包java类文件生成jar包. 方法一:(在项目工程没有引用外部jar包时,直接导出) 选中工程---->右键,Export. ...