制作时间:2009/10/17 14:00--2009/10/19 21:30
1.目标:有一个套餐Set,它有个属性是"指标"集合(Set ->Targets)
要求显示Set的同时,显示它的所有Target,并且可以增删改Set(包括修改它的Targets)
2.分析:
1.展示套餐(用DataGridView),其中套餐的Target集合属性(用Target拼接成的字符串显示)
2.增加套餐(新建窗体),其中Target集合(用CheckBoxList绑定)
3.修改套餐(和增加套餐用同一个窗体),只是先需要知道,修改哪个套餐(采用窗体间传值)
3.关键字 set(套餐) Target指标 SetForm(主窗体) UpdateSetForm(增加或修改套餐的窗体)
set和Target关系: set有个属性是Target集合
4.实现:
1.SetForm加载时,反序列化得到套餐集合(sets),并和DataGridView绑定,然后,给DataGridView的行头快捷菜单
2.UpdateSetForm窗体
1.先讨论"增加套餐"
1.在主窗体实例化UpdateSetForm之前,updateSetForm.Owner = this;这样把主窗体传给了updateSetForm
2.在UpdateSetForm窗体加载事件里
1.先得到主窗体setForm = (SetForm)this.Owner;
2.反序列化得到Target集合(targets)
3.判断,这里主窗体点的是"增加套餐",则什么也不做
3.确认按钮的单击事件
1.把控件的值 封装成一个套餐(set)
1.套餐的内容(Content) 如:身高¥30,体重¥40,B超¥50(是Target名和价格的组合)
2.遍历CheckBoxList.CheckedItems(和targets绑定),拼接得到套餐的内容,并计算得到套餐的价格
2.把这个套餐加到主窗体的sets集合里,并序列化到文件(即保存)
2."修改套餐"
1.在主窗体实例化UpdateSetForm之前,比"增加套餐"时多了一句
updateSetForm.Owner = this;
updateSetForm.Tag = sets[dgvSets.CurrentRow.Index];//把选中行对应的套餐放在窗体Tag里
2.在UpdateSetForm窗体加载事件里
1.判断,这里主窗体点的是"修改套餐"
1.把套餐的值 赋值窗体的文本框或CheckBoxList
1.因为套餐的内容(Content)是 形如:身高¥30,体重¥40,B超¥50
所以要分割2次,得到List<string> contents
2.遍历CheckBoxList,并用CheckBoxList.SetItemChecked(i,true);把他们选中
3.确认按钮的单击事件
1.把控件的值 封装成一个套餐(set) 同"增加套餐"
2.把主窗体里对应的套餐从集合(sets)里删除,然后,把修改好的插入进sets
因为,右键DataGridView修改的时候,会把当前行变为选中行(下面会有论述)
3.在CheckBoxList的chklTarget_SelectedIndexChanged事件里
1.txtPrice.Text = Convert.ToString(GetSet().Price);
表示点击一个Target复选框,则算出Target价格总和(即套餐的价格)
3.回到主窗体SetForm
1.右键选中DataGridView行
在DataGridView鼠标按下时的事件里(dgvSets_CellMouseDown)
if(e.Button==MouseButtons.Right&& e.RowIndex!=dgvSets.NewRowIndex
&& dgvSets.SelectedRows.Count<=1)
dgvSets.CurrentCell = dgvSets[0, e.RowIndex];
2.删除套餐(可删多行)
1.先得到选中行的整形集合(List<int> indexs)
2.循环遍历indexs,删除套餐
3.根据价格范围 查询
5.待改进
1.准备用DataSet做数据源,用集合做DataGridView数据源的弊端
1.删除多行时,不方便,(至今也没有找到一个可用的,总是有错!)
2.查询时,也不能用DataTable的DefaultView
2.准备把增加和修改作为主窗体的一部分(用面板),而不是新建一个窗体
6.心情
其实早就实现核心功能了,就是最近天冷,总是在屋子里,头有点晕
比如:删除的地方就想了1个小时,快捷菜单放在DataGridView行头,还有右键选中想了好几个小时
7.额外
foreach访问顺序 如果有5列,第1,2,4列被选中,访问顺序214
同理 如果有100列, 第11,12,13, 18,19,20, 77,78 访问顺序 13,12,11,20,19,18,78,77
即先访问第1串连续数(从后向前),再向后访问第2串连续数
用DataSet做的
======================
制作时间:2009/10/20 14:00--20:32
主要内容
1.DataGridView最好和DataSet绑定(可以自动排序,增删改很方便,查询用行过滤)
2.CheckBoxList和集合绑定比较好,
还有,重要属性和方法(items,CheckedItems,CheckedIndices,SetItemChecked(i,true))
3.统一了DataGridView的增加和修改界面
4.用CheckBoxList很好的解决了DataGridView的显示(当某项是集合时)
5.快捷菜单的位置,先初始化DataGridView时加载,然后,每加一项同时把快捷菜单加上(亮点,呵呵)
1.目标:有一个套餐Set(Name,price,description,content),其中套餐的content有指标集合组成(Targets)
实现套餐的增删改查
2.分析:主要是内容如何显示,和如何修改
1.把指标集合(Targets)拼接成字符串,来作为套餐的content
2.修改content时,把字符串再分解成指标集合(Targets),然后和CheckBoxList绑定
3.实现:
1.窗体加载事件
1.Set.xml(用来保存set集合),Target.xml(用来保存Target集合)
2.用DataSet读取并保存set.xml,用反序列化读取Target.xml,并用集合List<Target>保存
3.DataGridView显示套餐(和DataSet绑定),CheckBoxList显示指标集合(和List<Target>绑定)
2.删除套餐
1.遍历DataGridView,然后删除后保存
3.查询套餐
1.可用DataTable.DefaultView.RowFilter来过滤condition="Price >=min and Price <=max"
2.也可用此查询其他,比如查所有 condition="";
4.增加套餐
1.得到文本框和CheckBoxList的值,加到DataSet的行
string[] setRow = new string[]{txtName.Text,txtDescription.Text,price.ToString(),content };
ds.Tables[0].Rows.Add(setRow);
5.修改套餐
1.单击DataGridView的行,给文本框和CheckBoxList赋值
2.修改好后,得到文本框和CheckBoxList的值,加到DataSet的指定行
string[] setRow = new string[]{txtName.Text,txtDescription.Text,price.ToString(),content };
ds.Tables[0].Rows[dgvSets.CurrentRow.Index].ItemArray = setRow;
6.判断是"修改套餐"还是"增加套餐"
1.套餐名的文本框(txtName),按钮(btnChangeTxt),通过txtName是否为只读属性来判断
2.如果单击DataGridView某行,则txtName设为只读,此时为"修改"
如果点按钮btnChangeTxt,则改变txtName状态为可读写,此时为"增加"
7.额外功能
1.单击CheckBoxList某项,实时算出套餐价格
2."套餐名文本框"的只读属性,"允许输入"按钮,"确认"按钮 一起改变
1.单击DataGridView某项,则"套餐名文本框"为只读,"允许输入"按钮可用,"确认"按钮显示为修改
2.点击"允许输入"按钮后,则"套餐名文本框"为可读写,"允许输入"按钮禁用,"确认"按钮显示为增加
4.对CheckBoxList的理解
1.注意它的几个重要属性和方法(items,CheckedItems,CheckedIndices,SetItemChecked(i,true))
2.由于C#的CheckBoxList各个子项不能绑定2个值,所以很多时候,CheckedIndices更有用(可以当做集合索引)
5.需要的判断(比较重要的地方)
1.(SetForm_Load事件里)当删除所有的套餐项,并且退出后,再次打开就无法从Set.xml读取值了
所以,如果没有读到值,则从备用的SpareSet.xml里读
2.(dgvSets_CellMouseClick事件里)单击DataGridView,给右边文本框赋值时,需要判断DataGridView不是新行,
也不能是列头, 给CheckBoxList赋值时,要先清空,再赋值
3.(btnConfirm_Click事件里)增加套餐的时候,要保证套餐名不能重复
6.心情
把以前修改无数次的代码重新修订,发现了现在的些许进步,甚感高兴,呵呵
不过整个这次修订花了5天时间,还是多了点...