相信你一定有过这样类似的案例(这里我将举一个软件上传的例子)。
下面我先说一下我们一般开发这样的项目的时候所采取的方案。
一、MRS:
1、上传软件的程序开发,首先要给软件分类,如:多媒体软件、系统软件、网络软件等;
2、这些分类一定会持续一段时间,或者说近期内不会有变动(这里的变动指去除软件的某一类别)。
二、PES:
1、设计项目流程,制定开发时间;
2、设计页面,最终完成效果。
三、PIS:
1、数据库设计(一般我们首先会想到关联表来解决这样的问题)
表1:Driver表 (驱动信息表)
DriverID INT 4
DriverName NVarChar 100
DriverDate DateTime 8
表2:DriverType表 (驱动类型信息表)
DriverTypeID INT 4
DriverTypeName NVarChar 100
DriverTypeDate DateTime 8
表3:DriverAndDriverType (驱动和驱动类型的关系表)这个表显然是一个多对多的关系表
DriverID INT 4
DriverTypeID INT 4
2、存储过程(略)
3、主要类结构(略)
4、文件结构(略)
通过上面的设计,我们在提交一个驱动程序之后,便记录了该驱动的驱动类型,显然,实现这一功能需要一个
额外数据表的支持,即完成这项任务的工作全部交给了数据库。
今天我要介绍的这种方法将是没有额外表支持的。即仅仅在上面的一个表中增添了一个INT类型的字段。我们来看看:
一、MRS:
同上。这里注意:这些分类一定会持续一段时间,或者说近期内不会有变动(这里的变动指去除软件的某一类别)。
二、PES:
同上。
三、1、数据库设计
表1:Driver表 (驱动信息表)
DriverID INT 4
DriverName NVarChar 100
DriverDate DateTime 8
DriverType INT 4 (这个就是新增加的字段)
表2:DriverType表 (驱动类型信息表)
DriverTypeID INT 4
DriverTypeName NVarChar 100
DriverTypeDate DateTime 8
2、存储过程(略)这里所有逻辑均在程序里实现
3、主要类结构
使用这种方法,代码是关键,因为它涉及到很多进制转换的问题,主要是二进制与十进制之间的转换。下面我将按照
页面的流程作以说明。
上传软件,给软件选择类型,一般软件可以属于两种或两种以上类型,则可以多选,这里,你可以用ListBox或CheckBoxList
给用户提供选择,如:
软件名称:[ IE6.0 ]
软件类型:1、系统软件 2、网络软件 3、多媒体软件 (CheckBoxList形式)
提交 取消
这时假设用户选择1和2,则程序里可以这样处理:
double k = 0;
for (int i = 0; i < DriverType.Items.Count; i ++)
{
k += DriverType.Items[i].Selected ? Math.Pow(2,Convert.ToDouble(i)) : 0;
}
看懂了吧,我将选项看作一个反转的二进制数,选择第一个,就加2的0次方,选择第三个,就加2的2次方,最后存放到一个变量里。
而这个变量,恰恰就是你要存放到数据库中Driver表的DriverType字段的值,怎么样,满容易吧!
这里讲的是提交数据时如何获取十进制数,后面我将讲一下如何将取出的十进制数还原成一个反转的二进制数,并且根据0和1初始化
CheckBoxList。同时还将讲道最复杂的地方:列表显示数据,如何根据一个十进制数反映出该驱动都属于哪些类型。
下面我们继续说说如何将读取的十进制数付给CheckBoxList(初始化)。这里主要的就是一个小算法,我的这样:
private string MakeBanaryNum2(string mynum)
{
string k = "";
int num = Convert.ToInt16(mynum);
while (num / 2 != 0)
{
k += Convert.ToString(num % 2);
num = num / 2;
}
return k + "1";
}
之后将这个string类型的变量通过0和1判断初始化CheckBoxList:
string driverNum = MakeBanaryNum2(dataFromDataBase); //这里的入参就是数据库中存放的十进制数
for (int i = 0; i<driverNum.Length;i++)
{
if (driverNum[i] == '1')
chklst_DriverType.Items[i].Selected = true;
}
这个也相对容易。
最后我们来看看如何处理列表中的显示。在处理列表显示的问题时,因为你要将这个十进制数显转换成翻转二进制,之后还要根据0和1
以及他们的位置和书序对应DriverType表中的数据,转化成DriverName的内容。所以,最好是先将DriverType表中的数据取出,注意顺序
不能有变动(和插入的顺序相同),存放在一个集合里面。这里我恰好需要用到查询的DropDownList,里面恰好已经存放了所有的DriverTypeName,
所以,就直接利用了~~~不多说了,主要思想还是逐项比较,首先,将十进制数转换成反转二进制,之后,将这个反转二进制数与DropDownList
中的Value值求与,为真,则显示DropDownList中对应的Text值,否则不显示,这里我用到了DataGrid的Item_Bound方法。具体实现如下:
string dir = e.Item.Cells[3].Text; //获得显示该字段的单元格内容
string banaryNum2 = test.MakeBanaryNum2(dir,20); //将这个十进制数转换成翻转二进制
banaryNum2 = "0" + banaryNum2;
dir = "";
for (int i=0; i<drp_DriverType.Items.Count; i++)
{
if (banaryNum2[i] == '1')
dir += drp_DriverType.Items[i].Text + "/";
}
if (dir.Length != 0)
dir = dir.Substring(0,dir.LastIndexOf("/"));
e.Item.Cells[3].Text = dir; //重新给该单元格负值
现在,我们要做的工作就全部完成了,怎么样,有些收获吗??或许你很早就知道这种方法,或许你并不认为它是什么好的方案,我在这里只是
想和大家分享一下开发过程中的经验与收获,希望对你有些帮助,呵呵~~
花絮:开发过程中曾遇到很多问题,因为首次尝试。如:C#中,对Int16进行与操作,可以返回正确结果,但是对于Int32或者Int64就不是求
与了,呵呵,为什么?看看帮助吧~~
切记,使用该方法,一定不要删除任何的某一个类型(除了最后的没有用到的)!
FAQ:
1、为什么要用反转的二进制数?
答:因为方便填充控件。DataBind()就好。