WinForm界面开发之模块化分合
大千世界,合久必分,分久必合,分合之道,利之所趋。
开发过程,积少成多,聚沙成塔,模块之理,必经之路。
本文继续WInform界面开发系列的介绍,主要针对性介绍Winform开发过程中,经常用到的模块:数据字典模块、参数配置模块、权限管理模块的模块化应用,以及各模块的分合之道。
1、数据字典模块
我们知道,一般程序基本上都涉及到了一个是数据参考用途的数据字典模块,不管是Web还是Winform的,这个模块基本上是必不可少的,Winform的界面效果大致如下所示:
本模块的数据字典支持无限级树形分层应用,可以添加大类,字典项目等数据, 系统集成只需要拷贝相关的字典表即可实现集成。
2、参数配置模块
在程序中,一般应用就是通过代码把相关的内容进行转义保存或者解析,以便呈现给用户更好的数据展示效果,这个模块比较通用,可分可合。
另外一个也比较常用的就是参数的配置管理模块,一般如果参数比较少,直接使用.NET的配置保存功能即可,如下图所示。
但这种方式只能保存比较少的内容,对于比较复杂的配置,一般很少采用这种模式存放程序的参数信息,这种方式存储的参数,如果不是放到一个独立的文件中,还存在一个不同步的现象。
其实我们还是可以把参数的配置功能作为一个独立的模块进行处理,我的程序就是经常这么干的,而且由于是相对比较独立,并在设计时候就支持参数的编辑及展示功能,因此效率大大提高,对使用用户来说,由于修改界面比较统一,而且参数的说明等很丰富,因此用户修改系统的配置参数友好性大大增强,界面效果如下所示:
使用用户看到的参数配置界面效果:
开发者在设计时刻的参数配置界面如下所示:
这些参数最终目的是为了程序的读取和调用,调用代码非常简单,而且由于是强类型的属性以及良好的提示功能,应该是比较方便的,示例代码如下所示:

代码
double
hours
=
span.Hours;
hours
=
(hours
<
SystemConfig.Default.KFPartAtLeaseHoure)
?
SystemConfig.Default.KFPartAtLeaseHoure : hours;
//
最小的钟点房计费
if
(span.Minutes
<
60
&&
span.Minutes
>=
SystemConfig.Default.KFPartHourMinutes)
{
hours
+=
1
;
}
else
if
(span.Minutes
>
SystemConfig.Default.KFPartHalfHourMinte
&&
span.Minutes
<
SystemConfig.Default.KFPartHourMinutes)
{
hours
+=
0.5
;
}
其中的
SystemConfig.Default.KFPartAtLeaseHoure就是参数的名称了,根据这个名称就可以读取和设置该参数的值。
该参数配置模块是一个Visual Studio的Addin插件,因此可以在设计时刻提供参数的添加、修改、删除等支持,非常方便,而且也能在发布后给用户界面提供修改,是一个独立的模块。
3、权限管理模块
最后说说第三个模块,权限管理模块,我们知道,一般对于进销存或者稍微复杂一点的系统,都需要最基本的权限控制模块,以便控制不同用户的访问功能,这个可以做成独立的应用程序进行管理,如下图所示:
程序是一个独立的程序,但是权限系统需要和业务应用系统结合一起才有价值,因此它们之间的结合,一个除了数据库的整合(把权限系统需要的表整合一起),还需要在系统的代码中进行整合(实现功能模块的登陆及权限控制等)。登陆验证如下所示:
try
{
string
loginName
=
this
.cmbzhanhao.Text.Trim();
User userBLL
=
new
User();
string
identity
=
userBLL.VerifyUser(loginName,
this
.tbPass.Text, Guid.NewGuid().ToString());
if
(
!
string
.IsNullOrEmpty(identity))
{
UserInfo info
=
userBLL.GetUserByName(loginName);
#region
获取用户的功能列表
Function functionBLL
=
new
Function();
List
<
FunctionInfo
>
list
=
functionBLL.GetFunctionsByUser(info.ID,
"
HOTELMS
"
);
if
(list
!=
null
&&
list.Count
>
0
)
{
foreach
(FunctionInfo functionInfo
in
list)
{
if
(
!
Portal.gc.FunctionDict.ContainsKey(functionInfo.ControlID))
{
Portal.gc.FunctionDict.Add(functionInfo.ControlID, functionInfo);
}
}
}
#endregion
bLogin
=
true
;
Portal.gc.LoginInfo
=
info;
this
.DialogResult
=
DialogResult.OK;
}
else
{
MessageUtil.ShowTips(
"
用户帐号密码不正确
"
);
this
.tbPass.Text
=
""
;
//
设置密码为空
}
}
catch
(Exception err)
{
MessageUtil.ShowError(err.Message);
}
用户功能权限认证如下所示:
#region
KTV包间管理
if
(Portal.gc.HasFunction(
"
KTV
"
))
{
OutlookBarBand myBasicBand
=
new
OutlookBarBand(
"
KTV包间管理
"
);
myBasicBand.SmallImageList
=
this
.imageList;
myBasicBand.LargeImageList
=
this
.imageList;
if
(Portal.gc.HasFunction(
"
KTV/View
"
))
{
myBasicBand.Items.Add(
new
OutlookBarItem(
"
KTV包间状态视图
"
,
0
));
}
if
(Portal.gc.HasFunction(
"
KTV/Setting
"
))
{
myBasicBand.Items.Add(
new
OutlookBarItem(
"
KTV包间设置
"
,
1
));
}
if
(Portal.gc.HasFunction(
"
KTV/Goods
"
))
{
myBasicBand.Items.Add(
new
OutlookBarItem(
"
KTV商品设置
"
,
3
));
}
if
(Portal.gc.HasFunction(
"
KTV/Waiter
"
))
{
myBasicBand.Items.Add(
new
OutlookBarItem(
"
KTV服务生管理
"
,
4
));
}
if
(Portal.gc.HasFunction(
"
KTV/BookIn
"
))
{
myBasicBand.Items.Add(
new
OutlookBarItem(
"
KTV预订管理
"
,
5
));
}
if
(Portal.gc.HasFunction(
"
KTV/OtherIncome
"
))
{
myBasicBand.Items.Add(
new
OutlookBarItem(
"
KTV其他款项登记
"
,
6
));
}
myBasicBand.Background
=
SystemColors.AppWorkspace;
myBasicBand.TextColor
=
Color.White;
outlookBar1.Bands.Add(myBasicBand);
}
#endregion
至此,三个常用而且比较独立模块介绍完毕,这几种场景你用了几个呢,如果觉得有价值,欢迎一起讨论切磋。
开发之道,顺手拈来;分合之需, 顺其自然;优码不语,润物无声;