界面布局和交互设计本身有很多的学问,或者有很多艺术,但是本文这里先不讨论这个问题.
在QPG团队实践中,我们把界面划分成很多的UI_PART,这和ASP.NET2.0的WebPart可能有相同的地方.我们用这些简单的PART进行接受输入或者展示结果.这样就可以比较方便的测试了.通常这些PART就是一些用户控件,我们提供了IMainForm接口,使得UI的容器可以动态调入这些部件,哪怕程序已经运行,您也可以编写一个PART,您只要把它放到bin\plugins目录即可.
有时部件可能要和容器通讯,看看下面的代码您可能就会明白:
IMainForm 成员#region IMainForm 成员
public string CurUserID {
get {
// TODO: 添加 Form1.CurUserID getter 实现
return "admin";
}
}
public object getCookie(string name) {
// TODO: 添加 Form1.getCookie 实现
return name;
}
public void addCookie(string name, object obj) {
// TODO: 添加 Form1.addCookie 实现
}
public QPG.UIP.Privilege getPrivilegeByUser(string uid, string cmdName) {
// TODO: 添加 Form1.getPrivilegeByUser 实现
return QPG.UIP.Privilege.Full;
}
public void showStatus(string msg) {
MessageBox.Show(msg);
}
public void showHelp(string help) {
// TODO: 添加 Form1.showHelp 实现
}
public void showNotify(string title, string msg) {
MessageBox.Show(msg);
}
#endregion
要使用插件服务.您的代码Form容器大致如下:public string CurUserID {
get {
// TODO: 添加 Form1.CurUserID getter 实现
return "admin";
}
}
public object getCookie(string name) {
// TODO: 添加 Form1.getCookie 实现
return name;
}
public void addCookie(string name, object obj) {
// TODO: 添加 Form1.addCookie 实现
}
public QPG.UIP.Privilege getPrivilegeByUser(string uid, string cmdName) {
// TODO: 添加 Form1.getPrivilegeByUser 实现
return QPG.UIP.Privilege.Full;
}
public void showStatus(string msg) {
MessageBox.Show(msg);
}
public void showHelp(string help) {
// TODO: 添加 Form1.showHelp 实现
}
public void showNotify(string title, string msg) {
MessageBox.Show(msg);
}
#endregion
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);
}
}
}
具体代码可以参阅:下载开发演示文件