
置顶随笔
今天碰到一问题,原本一直运行没问题的代码,突然出错了。序列化某个对象时总是失败,错误信息:
at System.Xml.Serialization.TypeContainer.AddType()
at System.Xml.Serialization.TypeContainer.AddType()
at System.Xml.Serialization.XmlSerializationReflector.AddIXmlSerializableType()
at System.Xml.Serialization.XmlSerializationReflector.AddType()
at System.Xml.Serialization.XmlSerializationReflector.FindType()
at System.Xml.Serialization.XmlSerializationReflector.FindType()
.....
对象也不复杂:大致如下:
public class UpLoaderEntity
{
[XmlArray("FailedFiles", Namespace = "")]
[XmlArrayItem("UploadFailedFile", Namespace = "", Type = typeof(UploadFile))]
public List<UplodaFile> FailedFiles
{
get
{
if (this._FailedFiles == null)
{
this._FailedFiles = new List<UplodaFile> ( );
}
return this._FailedFiles;
}
}
[XmlArray("FinishFiles", Namespace = "")]
[XmlArrayItem("UploadFinishFile", Namespace = "", Type = typeof(string))]
public List<string> FinishFiles
{
get
{
if (this._FinishFiles == null)
{
this._FinishFiles = new List<string> ( );
}
return this._FinishFiles;
}
}
//出问题的就是这2个属性,其余属性略…
}
用google搜索了一下System.Xml.Serialization.TypeContainer.AddType(),果然发现了同样命苦的人。地址如下:http://www.zorched.net/2007/02/04/more-net-compact-framework-woes/
当你用到集合时,特别是泛型时,又用到重命名元素,或限制某个元素时(XmlElement,XmlArray,XmlArrayItem等等),会碰到这个问题。而且上面的代码在Full Framework中是没有任何问题的。
解决方法,利用强类型。将List<UploadFile>改为UploadFileCollectoin;List<string> 改为 StringCollection;
[Serializable]
public class UploadFileCollectoin : List<UploadFile>
{
}[Serializable]
public class StringCollection : System.Collections.ArrayList//List<string> {}
奇怪的是,这里当StringCollection 继承List<string>时竟然也不行,我改为ArrayList才解决了这个问题,当然,直接改为数组是最简单的,不过数组在使用时不太方便。
(环境:.net cf2.0,coolpad8260机器,wince5.0系统)
posted @
2008-04-02 17:08 风雨工作室 阅读(176) |
评论 (2) |
编辑
摘要: 2007-3-18 Wince5.0自定义ToolBar做WinCE的开发时,碰到一很头疼的事(Coolpad机器)。它的菜单很难看,字体很大,样式也太简单,就选用了 CF2.0中的ToolBar控件。用户使用后反应很大,普遍说是用不方便,因为Toolbar没有文本,只有图标。所以自定义一个Toolbar,这里不方便提供所有源码,只是讲述开发过程中碰到的几点问题(主要问题),相信对其他朋友有帮助。...
阅读全文
posted @
2008-03-19 11:43 风雨工作室 阅读(388) |
评论 (2) |
编辑
摘要: 最近刚完成一个在线更新的东西。因为智能手机应用没有Clickonce之类的更新程序,所以自己动手写一个。(其实clickonce也并不好用,自己动手写一个更方便).更新程序后台用webservice,httphandler都行,这里不多讲,主要讲讲前台设计。更新程序分为4个步骤:1.下载服务器版本及更新列表,对比本地的版本,是否需要更新;2.下载服务器的更新版本;3.覆盖本地版本;4.重新启动主应...
阅读全文
posted @
2007-08-28 10:22 风雨工作室 阅读(170) |
评论 (1) |
编辑
摘要: 上篇讲到一种不太合适的WebService接口设计方法,主要原因是,WebMethod的返回参数与入口参数为参数列表,所以当存在变更时,特别麻烦,需要修改WebService接口,客户端也要重新刷新WebService代理。所以这一次,改进了WebService的接口,所有的方法只有一个返回参数,一个入口参数。 修改接口如下:public interface IDALProvider { Sele...
阅读全文
posted @
2007-06-22 11:11 风雨工作室 阅读(225) |
评论 (1) |
编辑

2008年6月4日
DataGridView是Winform中最常用的控件之一,虽然它功能很强大,但是还是有一些功能没有提供,比如生成百分比的进度。代码如下:
public class DataGridViewProgressBarColumn : DataGridViewColumn

{
public DataGridViewProgressBarColumn()
: base(new DataGridViewProgressBarCell())

{
}
}

public class DataGridViewProgressBarCell : DataGridViewCell

{
public DataGridViewProgressBarCell()

{

}

//设置进度条的背景色;
public DataGridViewProgressBarCell(Color progressBarColor)
: base()

{
ProgressBarColor = progressBarColor;
}

protected Color ProgressBarColor = Color.Green; //进度条的默认背景颜色,绿色;

protected override void Paint(Graphics graphics, Rectangle clipBounds,
Rectangle cellBounds, int rowIndex,
DataGridViewElementStates cellState,
object value, object formattedValue,
string errorText, DataGridViewCellStyle cellStyle,
DataGridViewAdvancedBorderStyle advancedBorderStyle,
DataGridViewPaintParts paintParts)

{
using(SolidBrush backBrush = new SolidBrush(cellStyle.BackColor))

{
graphics.FillRectangle(backBrush, cellBounds);
}
base.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);

using(SolidBrush brush = new SolidBrush(ProgressBarColor))

{
int num = (int) value;
float percent = num / 100F;
graphics.FillRectangle(brush, cellBounds.X, cellBounds.Y+1, cellBounds.Width * percent, cellBounds.Height - 3);

string text=string.Format("{0}%", num);
SizeF rf=graphics.MeasureString(text,cellStyle.Font);
float x = cellBounds.X + (cellBounds.Width - rf.Width) / 2f;
float y = cellBounds.Y+ (cellBounds.Height - rf.Height) / 2f;
graphics.DrawString(text, cellStyle.Font, new SolidBrush(cellStyle.ForeColor),x,y);
}
}
}
Demo运行界面如下图:
posted @
2008-06-04 17:47 风雨工作室 阅读(169) |
评论 (5) |
编辑

2008年5月27日
最近刚好在写一份关于系统维护的应标书,突然对系统维护有了一点想法。
众所周知,系统维护是很头疼的,需要维护的有以下几个地方:
1. 在使用过程中用户提出新的需求变更,要求修改系统;
2. 系统有bug,需要修改完善;
3. 系统运行的外部环境发生变化,需改进行维护,比如:数据库迁移等;
系统维护面临的困难也有如下几点:
1. 你不是系统的最初开发组成员,理解别人的代码有难度;
2. 系统缺乏必要的项目文档,造成对业务不熟悉,对项目整体把握不足;
3. 代码不规范,造成代码可维护性不好;
4. 软件维护的工作没有吸引力,使维护的开发人员没有成就感。
我个人觉得要降低系统维护的成本,最主要的是代码质量,其次是业务流程文档,再次是开发文档。对程序员而言,最好的文档就是代码。良好的代码结构层次可以大大降低维护工作量。如何组织良好的代码结构是我想说的重点。我这里并不讨论多层数据访问,也不讨论OO的思想,想说说关于一些组织代码的细节。
场景1:我们常常遇到这种情况,有一ComboBox需要加载某基础数据项(假设为客户名称),需要用到 id和name两个属性;因为客户资料有多个地方用到,所以有多个界面用到类似的combobox。Binding数据的代码也都相同,分布在多个界面中。当初客户的需求是必须从下拉项中选择客户,所以多个界面也都设置好了属性,不允许编辑,只能从列表选择。现在客户改变了需求,需要增加查询的功能,在combobox中输入内容回车后,按模糊查询的结果列出来。于是一个一个界面的改,oh,my god,终于改完了。第2次,客户又提出类似的需求,要求对另一个基础数据(物料)也如此修改。开发人员又做重复劳动,一个一个界面改完了。那如果我们这些基础数据的列表集中起来管理不是更好吗?
那就建一个类:
public class CustomerComboBOxHelper
{
private ComboBox cmb = null;
public CustomerComboBOxHelper(ComboBox cmb)
{
this.cmb = cmb;
//do something;
}
}
这样所有需要用到客户资料ComboBox的界面,直接调用此方法,当然如果由工厂创建实例更好。类似的需求还有,有时我们需要多处用到级联的ComboBox,比如显示:省,市,选择某个省,列出省下面的所有城市,这样的控制代码显然是一样的,那么我们也可以把它封装在一起,节省维护的成本;
场景2:系统中用得非常多的消息提示(MessageBox),winform项目中到处都是类似这样的代码:MessageBox.Show("程序异常,请联系管理员!详细信息:" + ep.Message, xxxx系统, MessageBoxButtons.OK, MessageBoxIcon.Information);或者其它的类似的代码。客户提出需求变更,这样的错误消息提示不够友好,要求修改。你就慢慢一个一个去改吧。那为什么不把所有的MessageBox的方法封装在一起,包括显示错误消息,显示提示消息,显示Y/N,显示Ok/Cancel等等;参考代码:
public static class MessageBoxEx
{
public static DialogResult AskYesNo(string text)
{
//do some thing
}
public static DialogResult AskOkCancel(string text)
{
//do some thing
}
public static void ShowInfo(string text)
{
//do some thing
}
public static void ShowError(Exception ep)
{
//do some thing
}
}
当然,显示错误信息的方法单独写成一个类也行,这样如果想修改成自定义的界面显示错误消息,也仅仅只需要修改一处即可。
篇幅有限,上面讲的都是一些细节,这样的场景还有很多,但是它们都遵循一个原则,封装。尽可能使多处用到的代码封装在一起,辅以必要的注释,相信会大大减少项目维护的工作量。
posted @
2008-05-27 18:28 风雨工作室 阅读(106) |
评论 (1) |
编辑

2008年4月16日
今天才发现,原来KeyDown事件,处理不了Keys.Down,Keys.Up,Keys.Left,Keys.Right这4个键。当在窗体上按下这4个键时,会在窗体的控件上切换焦点,不会触发KeyDown事件。如何处理方向键呢,可以利用ProcessCmdKey,代码如下:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
const int WM_SYSKEYDOWN = 260;
const int WM_KEYDOWN = 256;
if(msg.Msg == WM_KEYDOWN || msg.Msg == WM_SYSKEYDOWN)
{
switch(keyData)
{
//do something
}
}
在这里可以处理方向键盘。
posted @
2008-04-16 23:52 风雨工作室 阅读(53) |
评论 (0) |
编辑

2008年4月2日
很高兴自己能收到一份月薪8k的邀请,比目前的薪水要高,心里很想跳巢过去。但是想想合作一年多的同事,彼此相处很开心,公司上下相处也不错,公司发展上路了,正处于快速发展期,我该放弃目前的机会,追求高薪?还是留下来和公司一起坚持到胜利?这几天很困惑,跟老大说了我想离职的想法。老大说感觉很诧异,第一时间给我打电话,让我留下来。做为公司核心开发人员,老大说真诚希望我留下来,虽然薪水比不上别人,但是公司年底的奖金一向不吝啬,去年底是近2w,今年不会让我失望的。我考虑3天,选择了留下来,希望公司发展更猛烈些,希望自己能保持高昂的斗志工作。做出了选择,心情也轻松了很多,既留之,则安之。祝福自己!
posted @
2008-04-02 17:33 风雨工作室 阅读(239) |
评论 (8) |
编辑
今天碰到一问题,原本一直运行没问题的代码,突然出错了。序列化某个对象时总是失败,错误信息:
at System.Xml.Serialization.TypeContainer.AddType()
at System.Xml.Serialization.TypeContainer.AddType()
at System.Xml.Serialization.XmlSerializationReflector.AddIXmlSerializableType()
at System.Xml.Serialization.XmlSerializationReflector.AddType()
at System.Xml.Serialization.XmlSerializationReflector.FindType()
at System.Xml.Serialization.XmlSerializationReflector.FindType()
.....
对象也不复杂:大致如下:
public class UpLoaderEntity
{
[XmlArray("FailedFiles", Namespace = "")]
[XmlArrayItem("UploadFailedFile", Namespace = "", Type = typeof(UploadFile))]
public List<UplodaFile> FailedFiles
{
get
{
if (this._FailedFiles == null)
{
this._FailedFiles = new List<UplodaFile> ( );
}
return this._FailedFiles;
}
}
[XmlArray("FinishFiles", Namespace = "")]
[XmlArrayItem("UploadFinishFile", Namespace = "", Type = typeof(string))]
public List<string> FinishFiles
{
get
{
if (this._FinishFiles == null)
{
this._FinishFiles = new List<string> ( );
}
return this._FinishFiles;
}
}
//出问题的就是这2个属性,其余属性略…
}
用google搜索了一下System.Xml.Serialization.TypeContainer.AddType(),果然发现了同样命苦的人。地址如下:http://www.zorched.net/2007/02/04/more-net-compact-framework-woes/
当你用到集合时,特别是泛型时,又用到重命名元素,或限制某个元素时(XmlElement,XmlArray,XmlArrayItem等等),会碰到这个问题。而且上面的代码在Full Framework中是没有任何问题的。
解决方法,利用强类型。将List<UploadFile>改为UploadFileCollectoin;List<string> 改为 StringCollection;
[Serializable]
public class UploadFileCollectoin : List<UploadFile>
{
}[Serializable]
public