随笔-21  评论-29  文章-0  trackbacks-4
  置顶随笔
 

今天碰到一问题,原本一直运行没问题的代码,突然出错了。序列化某个对象时总是失败,错误信息:

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年7月30日
     摘要:   阅读全文
posted @ 2008-07-30 14:14 风雨工作室 阅读(120) | 评论 (0)编辑
  2008年6月4日
      DataGridViewWinform中最常用的控件之一,虽然它功能很强大,但是还是有一些功能没有提供,比如生成百分比的进度。代码如下:
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年6月3日
代码很简单:
private void RecursiveDirectory(DirectoryInfo folder)
        
{
            FileInfo[] files 
= folder.GetFiles();  
            
foreach(FileInfo file in files)
            
{
               
//do something
            }


            DirectoryInfo[] subFolders 
= folder.GetDirectories( );
            
if(subFolders == null || subFolders.Length == 0)
            
{
                
return;
            }

            
foreach(DirectoryInfo subFolder in subFolders)
            
{
                
if(_isCancel)
                
{
                    
return;
                }

                RecursiveDirectory(subFolder);
            }

        }
调用:
DirectoryInfo root = new DirectoryInfo(path);
RecursiveDirectory(root);

递归的算法很简单,如果能掌握其精神,任何类似的代码都是手到擒拿。
posted @ 2008-06-03 17:14 风雨工作室 阅读(27) | 评论 (0)编辑
  2008年5月27日
      最近刚好在写一份关于系统维护的应标书,突然对系统维护有了一点想法。

众所周知,系统维护是很头疼的,需要维护的有以下几个地方:

1. 在使用过程中用户提出新的需求变更,要求修改系统;

2. 系统有bug,需要修改完善;

3. 系统运行的外部环境发生变化,需改进行维护,比如:数据库迁移等;

系统维护面临的困难也有如下几点:

1. 你不是系统的最初开发组成员,理解别人的代码有难度;

2. 系统缺乏必要的项目文档,造成对业务不熟悉,对项目整体把握不足;

3. 代码不规范,造成代码可维护性不好;

4. 软件维护的工作没有吸引力,使维护的开发人员没有成就感。

我个人觉得要降低系统维护的成本,最主要的是代码质量,其次是业务流程文档,再次是开发文档。对程序员而言,最好的文档就是代码。良好的代码结构层次可以大大降低维护工作量。如何组织良好的代码结构是我想说的重点。我这里并不讨论多层数据访问,也不讨论OO的思想,想说说关于一些组织代码的细节。

场景1:我们常常遇到这种情况,有一ComboBox需要加载某基础数据项(假设为客户名称),需要用到 idname两个属性;因为客户资料有多个地方用到,所以有多个界面用到类似的comboboxBinding数据的代码也都相同,分布在多个界面中。当初客户的需求是必须从下拉项中选择客户,所以多个界面也都设置好了属性,不允许编辑,只能从列表选择。现在客户改变了需求,需要增加查询的功能,在combobox中输入内容回车后,按模糊查询的结果列出来。于是一个一个界面的改,ohmy 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.Right4个键。当在窗体上按下这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月14日
 

总是记不住上月社保是多少,所以花了半天写了一个记录工具,保存每次查询记录,避免忘记了。界面如下:
    

使用很简单,首先设置自己的社保电脑号,然后查询,工具会自动按月保存查询记录,重复记录不会保存。

代码实现其实也很容易,利用HttpWebRequest获得Response,然后利用正则表达式获取想要的数据。   

下载:/Files/michael-zhangyu/ssquery.rar
posted @ 2008-04-14 11:00 风雨工作室 阅读(951) | 评论 (6)编辑
  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