WinForm界面开发之酒店管理系统--控件篇
在上篇《
WinForm界面开发之酒店管理系统--开篇
》中介绍了一些界面的东西,本篇开始抽丝剥茧,细致分析里面的控件组成,并公布相关的控件资源,以飨读者。
1、按钮控件
首先介绍一个按钮控件,这个是一个Vista样式的控件,其代码是在Codeproject上有的:
http://www.codeproject.com/KB/buttons/VistaButton.aspx
通过改变其颜色,就可以实现不同的效果,而且鼠标靠近或者离开都有特殊的效果,比较酷。例如我加上颜色图片后,得到的效果如下所示:
2、Tab控件
在使用Tab控件做那个房间状态视图的时候,由于内置的Tab控件样式感觉不是很满意,我参考过很多不一样的控件,我觉得比较好的一个是Codeproject上的一个中国人在日本发表的一篇控件文章:
http://www.codeproject.com/KB/tabs/CustomizedTabcontrol.aspx
,控件的界面大致如下。
虽然我因为样式冲突的问题,最终没有使用上她的控件,不过我觉得是很不错的,由于她的控件在Fill状态下有点问题,特意请教了她,并得到了她的最新控件代码,我上传到博客上,给大家下载参考吧:
https://files.cnblogs.com/wuhuacong/CustomTabcontrol.rar
。
我做的控件大致的思路是先设计一个窗口框架,里面的Tabpage可是通过代码增加的,由于客房的房间类型是动态变化,而不是固定的,如下图所示。我们每次New出一个TabPage的时候,把有图标的用户控件加载(下一个图)进去就可以了。
下面这个是Winform的用户控件,它的职责就是获取数据库的房间信息,根据不同的状态显示不同的图标,然后动态创建,每种房间类型有多少个房间,就动态创建多少个。如下图所示。
另外我们还需要它绑定相关的业务菜单,根据不同的状态,禁用或者显示特定的菜单,如下图所示。
这样我们在最终的界面上就少管很多事情,这样层层下去,各管各的事情,互不干扰。
这个控件会公布一些事件,让外部进行相关的操作,如下代码所示:
代码
public
delegate
void
ShowStatusHandler(RoomInfo roomInfo);
public
ShowStatusHandler OnShowStatus
=
null
;
另外,它也会公布一些接口,给Ower对他进行相关的管理,主要是改变视图类型(大图标、小图标、列表显示),改变房间状态(空闲、占用、预定等),以及强制刷新操作。如下代码所示。
代码
///
<summary>
///
修改ListView的视图
///
</summary>
///
<param name="viewType"></param>
public
void
ChangeViewType(View viewType)
{
this
.listView1.View
=
viewType;
BindData();
this
.Refresh();
}
///
<summary>
///
修改房间的状态显示
///
</summary>
///
<param name="roomStatus"></param>
public
void
ChangeRoomStatus(
string
roomStatus)
{
this
.RoomStatus
=
roomStatus;
BindData();
this
.Refresh();
}
public
void
UpdateStatus()
{
BindData();
this
.Refresh();
}
搞定了小的,现在开始搞大的了,就是该用户控件的Owner窗体,它负责很多个这样的用户控件的创建、更新等操作。下面看看代码先。
代码
///
<summary>
///
更新所有房间的状态显示
///
</summary>
public
void
UpdateStatus()
{
foreach
(TabPage page
in
this
.tabControl1.TabPages)
{
foreach
(Control control
in
page.Controls)
{
RoomViewControl lvwControl
=
control
as
RoomViewControl;
if
(lvwControl
!=
null
)
{
lvwControl.UpdateStatus();
}
}
page.Refresh();
}
}
public
void
ChangeViewType(View viewType)
{
foreach
(TabPage page
in
this
.tabControl1.TabPages)
{
foreach
(Control control
in
page.Controls)
{
RoomViewControl lvwControl
=
control
as
RoomViewControl;
if
(lvwControl
!=
null
)
{
lvwControl.ChangeViewType(viewType);
}
}
page.Refresh();
}
}
public
void
ChangeRoomStatus(
string
roomStatus)
{
foreach
(TabPage page
in
this
.tabControl1.TabPages)
{
foreach
(Control control
in
page.Controls)
{
RoomViewControl lvwControl
=
control
as
RoomViewControl;
if
(lvwControl
!=
null
)
{
lvwControl.ChangeRoomStatus(roomStatus);
}
}
page.Refresh();
}
}
上面的代码,其实就是遍历其TabPage中的控件,并判断是否特定的控件,然后进行相关的操作,就是调用每一个控件公布的接口。
由于控件的变化,需要通知状态视图,进行相应的显示,如下图所示。
要实现动态的状态变化,那么就需要注册状态变化的事件了,我们在构建该用户控件的时候,注册它的变化事件相应即可。如下代码所示
代码
private
void
Form1_Load(
object
sender, EventArgs e)
{
#region
根据不同的房间类型创建不同的Tab和房间视图
this
.tabControl1.TabPages.Clear();
List
<
RoomTypeInfo
>
roomTypeList
=
BLLFactory
<
RoomType
>
.Instance.GetAll();
foreach
(RoomTypeInfo info
in
roomTypeList)
{
TabPage page
=
new
TabPage();
page.Text
=
info.Name;
page.Tag
=
info;
RoomViewControl viewControl
=
new
RoomViewControl();
viewControl.RoomType
=
info.Name;
viewControl.Dock
=
DockStyle.Fill;
viewControl.OnShowStatus
=
new
RoomViewControl.ShowStatusHandler(OnShowStatus);
page.Controls.Clear();
page.Controls.Add(viewControl);
this
.tabControl1.TabPages.Add(page);
}
#endregion
}
下面的代码是就是事件响应代码,它的功能就是完成状态的更新显示,以及房价费用的显示。如下图所示。
代码
private
void
OnShowStatus(RoomInfo roomInfo)
{
decimal
allMoney
=
0.0M
;
#region
更新消费记录
if
(roomInfo
!=
null
)
{
List
<
ConsumerListInfo
>
consumerList
=
BLLFactory
<
Room
>
.Instance.GetAllConsumption(roomInfo.RoomNo);
this
.listView1.Items.Clear();
int
i
=
1
;
foreach
(ConsumerListInfo info
in
consumerList)
{
ListViewItem item
=
new
ListViewItem(i.ToString());
item.SubItems.Add(info.RoomNo);
item.SubItems.Add(info.ItemName);
item.SubItems.Add(info.Price.ToString(
"
C2
"
));
item.SubItems.Add(info.Discount.ToString());
item.SubItems.Add(info.DiscountPrice.ToString(
"
C2
"
));
item.SubItems.Add(info.Quantity.ToString());
item.SubItems.Add(info.Amount.ToString(
"
C2
"
));
item.SubItems.Add(info.BeginTime.ToString());
item.SubItems.Add(info.Waiter);
item.SubItems.Add(info.Creator);
if
(info.Quantity
<
0
)
{
item.ForeColor
=
Color.Red;
}
this
.listView1.Items.Add(item);
allMoney
+=
info.Amount;
i
++
;
}
}
#endregion
#region
更新房间信息
FrmStatus dlg
=
Portal.gc.MainDialog.mainStatus;
if
(dlg
!=
null
)
{
if
(roomInfo
!=
null
)
{
InitDisplayItems(dlg.DisplayItems, roomInfo, allMoney);
dlg.UpdateContent();
}
else
{
dlg.InitDisplayItems();
dlg.UpdateContent();
}
}
//
Portal.gc.MainDialog.ShowMainStatusWin();
#endregion
this
.lblAmount.Text
=
string
.Format(
"
消费总金额:{0:C2}
"
, allMoney);
}
好了,描述与代码齐上,虽不齐整,但希望抛砖引玉能,给各位读者的思绪及灵感有一个引桥般的铺垫,完毕收工。