技术篇(3)--QPG界面分解方法介绍
在实际开发中,我发现很多程序员花很多时间在界面处理上.并且界面之间的关系和控制逻辑可能工作量并不小.所以好些老手到后面就跑去做后台服务,做通讯去了.
界面布局和交互设计本身有很多的学问,或者有很多艺术,但是本文这里先不讨论这个问题.
在QPG团队实践中,我们把界面划分成很多的UI_PART,这和ASP.NET2.0的WebPart可能有相同的地方.我们用这些简单的PART进行接受输入或者展示结果.这样就可以比较方便的测试了.通常这些PART就是一些用户控件,我们提供了IMainForm接口,使得UI的容器可以动态调入这些部件,哪怕程序已经运行,您也可以编写一个PART,您只要把它放到bin\plugins目录即可.
有时部件可能要和容器通讯,看看下面的代码您可能就会明白:
插件的编写就很简单了,大致如下:
具体代码可以参阅:下载开发演示文件
界面布局和交互设计本身有很多的学问,或者有很多艺术,但是本文这里先不讨论这个问题.
在QPG团队实践中,我们把界面划分成很多的UI_PART,这和ASP.NET2.0的WebPart可能有相同的地方.我们用这些简单的PART进行接受输入或者展示结果.这样就可以比较方便的测试了.通常这些PART就是一些用户控件,我们提供了IMainForm接口,使得UI的容器可以动态调入这些部件,哪怕程序已经运行,您也可以编写一个PART,您只要把它放到bin\plugins目录即可.
有时部件可能要和容器通讯,看看下面的代码您可能就会明白:
IMainForm 成员
要使用插件服务.您的代码Form容器大致如下:public class Form1 : System.Windows.Forms.Form,IMainForm
{
private System.ComponentModel.IContainer components;
private System.Windows.Forms.Panel panel1;
public static PluginService Plugins=new PluginService();
private QPG.UIP.Actions.ActionList actionList1;
private QPG.UIP.Actions.Action action1;
private QPG.UIP.Actions.Action action2;
//
protected IPlugin selectedPlugin;
public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
Plugins.MainForm=this;
action1.Tag="Demo.UIC.Plugin1";
action2.Tag="Demo.UIC.Plugin2";
action1.Execute+=new EventHandler(runAction);
action2.Execute+=new EventHandler(runAction);
// Tester t=new Tester();
// t.testParametersConfig();
}
private void runAction(object sender, System.EventArgs e) {
QPG.UIP.Actions.Action a=sender as QPG.UIP.Actions.Action;
if(getPrivilegeByUser("admin", a.Tag.ToString())==Privilege.None) return;
selectedPlugin=Plugins.FindPlugin(a.Tag.ToString() );
panel1.Controls.Clear();
panel1.Controls.Add(selectedPlugin.MainInterface);
selectedPlugin.MainInterface.Dock=DockStyle.Fill;
}
{
private System.ComponentModel.IContainer components;
private System.Windows.Forms.Panel panel1;
public static PluginService Plugins=new PluginService();
private QPG.UIP.Actions.ActionList actionList1;
private QPG.UIP.Actions.Action action1;
private QPG.UIP.Actions.Action action2;
//
protected IPlugin selectedPlugin;
public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
Plugins.MainForm=this;
action1.Tag="Demo.UIC.Plugin1";
action2.Tag="Demo.UIC.Plugin2";
action1.Execute+=new EventHandler(runAction);
action2.Execute+=new EventHandler(runAction);
// Tester t=new Tester();
// t.testParametersConfig();
}
private void runAction(object sender, System.EventArgs e) {
QPG.UIP.Actions.Action a=sender as QPG.UIP.Actions.Action;
if(getPrivilegeByUser("admin", a.Tag.ToString())==Privilege.None) return;
selectedPlugin=Plugins.FindPlugin(a.Tag.ToString() );
panel1.Controls.Clear();
panel1.Controls.Add(selectedPlugin.MainInterface);
selectedPlugin.MainInterface.Dock=DockStyle.Fill;
}
插件的编写就很简单了,大致如下:
using System;
using QPG.UIP;
namespace Demo.UIC
{
/// <summary>
/// Plugin2
/// </summary>
public class Plugin1 : BasePlugin
{
public Plugin1():base()
{
}
protected override void init()
{
base.init();
this.myRequimentNo = "uca01";
this.myDescription="统计图";
this.myAuthor="alex";
}
public override void Initialize()
{
this.MainInterface=new PlugUI1();
}
public override void Dispose()
{
//Put any cleanup code in here for when the program is stopped
}
}
}
using QPG.UIP;
namespace Demo.UIC
{
/// <summary>
/// Plugin2
/// </summary>
public class Plugin1 : BasePlugin
{
public Plugin1():base()
{
}
protected override void init()
{
base.init();
this.myRequimentNo = "uca01";
this.myDescription="统计图";
this.myAuthor="alex";
}
public override void Initialize()
{
this.MainInterface=new PlugUI1();
}
public override void Dispose()
{
//Put any cleanup code in here for when the program is stopped
}
}
}
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using QPG.UIP;
namespace Demo.UIC
{
/// <summary>
/// Summary description for ctlMain.
/// </summary>
public class PlugUI1 : PluginBaseUI
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.TextBox txtFeedback;
private System.Windows.Forms.Button button1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public PlugUI1()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
// TODO: Add any initialization after the InitializeComponent call
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
//
private void button1_Click(object sender, System.EventArgs e) {
this.PluginHost.showStatus(txtFeedback.Text);
}
}
}
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using QPG.UIP;
namespace Demo.UIC
{
/// <summary>
/// Summary description for ctlMain.
/// </summary>
public class PlugUI1 : PluginBaseUI
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.TextBox txtFeedback;
private System.Windows.Forms.Button button1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public PlugUI1()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
// TODO: Add any initialization after the InitializeComponent call
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
//
private void button1_Click(object sender, System.EventArgs e) {
this.PluginHost.showStatus(txtFeedback.Text);
}
}
}
具体代码可以参阅:下载开发演示文件