C#编程笔记(二)
续前文。
(4)用户自定义控件
用户在提需求的时候,希望Button之类的图标能够更漂亮一些,圆角矩形那种的,开始的时候孤陋寡闻,不知道这个东西还能咋变化,跟人说这个不太可能。后来逼急了,在网上一顿搜,才知道了用户自定义控件这个东西,找到一处叫ImageButton的,这个在asp上是有的,但是在WinForm上没有,有牛在WinForm中自定义了一个,豁然开朗,太爽了!
这个东西从CodeProject上找到的WinForm ImageButton,作者是一仅有13岁的美国小童鞋,大赞啊。
我仅说说我用到的一点吧:你可以给一个ImageButton指定NormalImage,DownImage,HoverImage,其他参数默认,运行之后,可以看到一个Button图标的动画效果,很不错的。
不多说了,借来的东西,分享出来了:)
(5)增强的ListView -- XPTable
这又是一个从CodeProject上借来的宝贝,XPTable。
不得不说,这个东西太强大了,我因为他的出现,对整个工程进行了一次翻工。
第二个版本提交后,用户觉得以前用的那种动态生成组件出来的效果太虎了……一点都不美观,像在查看所有数据时用的ListView就非常好。但是,在MSDN上说,ListView是不能编辑的,DataGridView又暂时玩不来,只能又在网上找。
吸取了ImageButton的经验,这次刻意找了找用户自定义的ListView,又想起Java的第三方控件,也加入了搜索的范围。开始的时候,在慧度控件网上,找到一个叫RichListView,有RicherComponents开发的,东西是不错,可惜收费的,试用版会留有标记,只得作罢。
终于,还是在CodeProject上找的了XPTable,这个东西,我觉得比原有的ListView强大了好多,支持编辑,支持在ListView中插入原来无法加入的空间,我觉得,对我做的项目而言,帮了很大的忙。
(5.1)加入工具箱
“工具箱”》“右键”》“添加选项卡”》“XPTable”》“右键XPTable”》“选择项”》打开“选择工具箱项”窗口》“浏览”选择XPTable.dll》“确定,这样,就将XPTable添加到了工具箱中。
(5.2)往XPTable中绑定数据
就是把指定的XML文件中的数据,绑定到XPTable上显示出来。这里,我用到了两种Column:TextColumn和ComboxColumn。
2 {
3 this.table1.BeginUpdate();
4
5 TextColumn IDColumn = new TextColumn("ID", 70);
6 IDColumn.Editable = false;
7
8 TextColumn ContentColumn = new TextColumn("Content", this.table1.Width - 170);
9 ContentColumn.Editable = false;
10
11 ComboBoxColumn resultColumn = new ComboBoxColumn("Yes/No", 70);
12
13 this.table1.ColumnModel = new ColumnModel(new Column[] { IDColumn, ContentColumn, resultColumn });
14
15 TableModel myRows = new TableModel();
16
17 XmlDocument xDoc = new XmlDocument();
18 xDoc.Load(this._fileName);
19 XmlNode root = xDoc.ChildNodes.Item(1).ChildNodes.Item(0);
20 this._count = root.ChildNodes.Count;
21
22 foreach (XmlNode xNode in root.ChildNodes)
23 {
24 myRows.Rows.Add(new Row(new Cell[] { new Cell(xNode.ChildNodes[0].InnerText), new Cell(xNode.ChildNodes[1].InnerText), new Cell(" ") }));
25 }
26
27 this.table1.TableModel = myRows;
28
29 this.table1.TableModel.RowHeight = 21;
30
31 this.table1.BeginEditing += new XPTable.Events.CellEditEventHandler(table_BeginEditing);
32
33 this.table1.EndUpdate();
34 }
35
36 private void table_BeginEditing(object sender, XPTable.Events.CellEditEventArgs e)
37 {
38 if (e.Editor is ComboBoxCellEditor)
39 {
40 if (e.Column == 2)
41 {
42 ((ComboBoxCellEditor)e.Editor).Items.Clear();
43 ((ComboBoxCellEditor)e.Editor).Items.AddRange(new string[] { " ", "Yes", "No" });
44 }
45 }
46 }
这里有个问题是Combox的List中的内容,需要一个单独的事件来处理,如上所示。
总结地说,借用别人的东西,快速地上手,帮自己完成了任务,但是确实有些东西知其然不知其所以然,消化吸收还有很长的路。
(6)补充
很有一些零散的问题,在做的过程中遇到了麻烦,这里再补充下。
(6.1)Panel的鼠标滚动事件处理
用户在谈论过程中,觉得看那么多一条一条的东西,最好要能支持滚轮,但这个东西不是在属性框里面设几个参数就完成的,我一开始就没做,后来只得再加上。
以下代码参考了网上一童鞋的工作,在此谢过了先。
2 {
3 int mVSValue = this.panel1.VerticalScroll.Value;
4 int pScrollValueDelta = e.Delta;
5
6 if ((mVSValue - pScrollValueDelta) <= this.panel1.VerticalScroll.Minimum)
7 {
8 this.panel1.VerticalScroll.Value = this.panel1.VerticalScroll.Minimum;
9 }
10 else if ((mVSValue - pScrollValueDelta) >= this.panel1.VerticalScroll.Maximum)
11 {
12 this.panel1.VerticalScroll.Value = this.panel1.VerticalScroll.Maximum;
13 }
14 else
15 {
16 this.panel1.VerticalScroll.Value -= pScrollValueDelta;
17 }
18
19 if (this.panel1.VerticalScroll.Value != mVSValue)
20 {
21 return;
22 }
23
24 this.panel1.Refresh();
25 this.panel1.Invalidate();
26 this.panel1.Update();
27
28
29 }
30
31 private void panel1_MouseDown(object sender, MouseEventArgs e)
32 {
33 this.panel1.Focus();
34 }
当然,还要将上面的两个事件绑定到Panel控件上。
不过,存在的一个问题是,开始的时候,在Panel内怎么点,都找不到焦点,滚轮没用,总得等上一会儿,再点才管用。开始,我以为是焦点定位的问题,在里面的Panel里面嵌套的控件上也加上Panel焦点的获取,还是不行;后来,发现需要在Panel里面的TextBox上点一下,进入编辑状态之后,就可以快速地响应滚轮事件,但是,对于没有TextBox编辑的Panel,等上一会儿,也能响应……凌乱了……求达人指教。
还有,自带的ListView控件没法响应滚轮事件,在网上找了一堆,发现没有人像处理Panel那样简单地响应滚轮,倒是MSDN上,有人从底层代码上做……各种不懂……求指教。
(6.2)打印出Doc文档
我一直想做一个功能,就是能把最后答题的结果,输出到一个Dot模板上,生成一份Doc形式的答题报告。虽然用户没提,但我真的是想做这件事儿。
但是吧,在网上找了好久,下了若干样例,总是会有这样那样的问题,最主要的一个就是在打开Dot模板的时候报错,出现如下的提示:
我断点跟了下,发现时在打开模板的时候出的问题,之后又会出现下面的错误,就再没法做了……
早有心好好弄一下C#操作office这部分东西,我仅试过word,但是每次总是不能令人满意,也在网上找了各种资料,发现大家行得通的,在我这儿就总会出点问题,唉,求教啊……
要说一下,我在做的时候,是先做好一个模板,然后在模板里面的打算要添加内容的位置加上标签。在C#操作dot文档的时候,其实就是向指定的标签处添加内容。
我参考的是百度文库上一童鞋的工作通
That‘s all.
总得来说,做了这么一件事儿,从中发现了很多的不足,也借机逼着自己学会了很多东西。很多时候,没有需求,为学而学地去看一些书,并没有什么效果,倒不如直接拿一件事情来做,你会遇到一些你可能从来没有想到过的问题,然后想尽各种方法,解决的。后者可能学地更透一些,更实用一点。
在做事的过程中,学习、引用、借鉴了别人的好多东西,“君子生非异也,善假于物也”,学会借力,也是一种学习能力吧,呵呵,惭愧了,向那么多学习借鉴过的童鞋们致敬了。