标签式用户界面的故事

 
软件的用户界面,正如女性的时装,每过一段时间就有一种新的款式。自从图形用户界面诞生以来,窗口作为一种主流的设计模式,尽管一直是这样的方方正正、层层叠叠,以前有棱角的地方却慢慢露出了优美的曲线,过去严实和保守的色调也变得越来越清凉和透明。在紧贴着这层靓丽外表的里面,内容组织的方式也在悄悄地发生着变化。当年风靡一时的MDI模式一夜之间突然让人觉得是如此的凌乱和繁杂,反而当时只是在后台的参数设置界面上使用的标签模式,如今变成了主界面上倍受尊宠的明星。更有甚者,在微软的office 2007里面,连菜单都标签化了。

 

 

其实开始接触标签式用户界面已经是几年前的事了,当时为了设计一个可用性更好的用户界面,我们参考了不少业界巨头,最后还是比较喜欢Siemens和GE的某些医学影像产品里的标签式风格。用软件的术语,就是去掉繁琐的菜单,而用标签这种清晰简单的交互方式,让用户在几个主要的业务模块之间进行导航。在程序的实现上,为了实现不同业务模块的解偶和并行开发,当时我们采用了一些复杂的方式。尤其是如何让一个界面既能在自己的进程中独立运行,又能嵌入到标签页中与来自其他业务模块的界面一起在主进程中运行,当时调用了其他一些组件,代码写出来,编译通过,我也懒得深究了。现在有时间来回顾一下,才发现原来换一种方式,也可以如此的简单。

在.NET的世界中,如果一个界面能独立运行,它就必须是个Form,比如:
 
Form2 frm  =   new  Form2();
Application.Run(frm);

而通常我们印象中能嵌入标签页控件TabControl中的,又必须是个Control,比如:

TabPage page  =   new  TabPage(  " test "  );
TextBox text 
=   new  TextBox();
page.Controls.Add( text );
this .tabControl1.TabPages.Add( page );

虽然Form派生于Control,但直接把一个Form的对象Add到一个TabPage上却是不行的,要想Add成功,就要把Form指定为一个子窗口,即设定一下TopLevel和Parent这两个属性。

TabPage page  =   new  TabPage(  " test "  );
            
Form2 frm 
=   new  Form2();
frm.FormBorderStyle 
=  FormBorderStyle.None;
frm.Dock 
=  DockStyle.Fill;
frm.TopLevel 
=   false ;
frm.Visible 
=   true ;
frm.Parent 
=  page;
            
page.Controls.Add( frm );
this .tabControl1.TabPages.Add( page );

 

这里我们发现,把FormBorderStyle设置为None以后,窗口上的菜单就消失了。但如果没有把它设置为None,Form2嵌入到TabControl来以后还会带着它的标题栏,这就很难看了。不过可以考虑采用以前MDI时代的做法,当主窗口Form1发现当前嵌入的子窗口有菜单的时候,就自动把这个菜单显示到主窗口上。另外,如果要做一个商业软件,直接用.NET自带的TabControl来做标签式界面是难以想象的,因为这个控件实在太丑了,而且你也休想通过重载它的一些成员来让它变得更漂亮些。最好还是重新写一个TabControl吧,其实很容易的。尤其是应该多用一些像Panel这样简洁明了的控件,然后就像在网页上显示大张图片时常采用的那种拼贴艺术一样把它们拼贴起来就好了,运气好的话,甚至只需要设置一下Align、Anchor或者Dock属性,不需要直接动用任何一个GDI/GDI+的API。这就是WinForm的威力。最后,不管如何自定义控件,把窗口嵌入控件的方式永远都是这么的简单。

 

前面我们讲O/X Mapping和O/R Mapping的故事中,都提到了插件机制。其实如果想让插件中包含用户界面的话,除了把托管的插件模块(不管是EXE还是DLL)用Assembly.Load()转载上来以外,还需要用上面的方法把他们嵌入到主界面上。当然,在详细设计的时候,还是要有定义一些公共的接口、所有插件都实现这些接口之类的考虑,但这些都是基本的设计常识,不再详述了。总之,这样一来,这些模块真的就既能独立运行,独立开发,独立调试,又能嵌入宿主进程中,与大家一起运行了。天哪,与大家一起运行?这可没那么容易。对了,我们还需要一个模块之间相互通信的机制;如果系统足够复杂,还需要一个工作流引擎来确保这些通信的有序的,可管理的。好的,这又是个大话题,且听下回分解吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值