在制作一个批量序列化工具时遇到了如下问题,在此记录一下,仅供参考。

      主程序加载另一个程序集,将其中的所有类取出,然后对这些类分别调用泛型类或泛型方法。控制台程序解决方案如下:

  • Main工程:提供Worker类进行数据操作,XMLTool<T>泛型类将数据集序列化为.xml文档,RootCollection<T>类封装数据集
    • Worker

           提供成员方法void DoWork<T>()、List<T> GetList<T>()、静态成员方法StaticDoWork<T>(),代码如下:

     1 public class Worker
    2 {
    3 public Worker()
    4 {
    5 }
    6
    7 public void DoWork<T>()
    8 {
    9 Type t = typeof(T);
    10 Console.WriteLine("Get Class: {0}", t.Name);
    11 PropertyInfo[] properties = t.GetProperties();
    12 foreach (PropertyInfo property in properties)
    13 {
    14 Console.WriteLine("\tproperty.Name: " + property.Name + "\tproperty.MemberType: " + property.PropertyType);
    15 }
    16 }
    17
    18 public static void StaticDoWork<T>()
    19 {
    20 Type t = typeof(T);
    21 Console.WriteLine("Get Class: {0}", t.Name);
    22 PropertyInfo[] properties = t.GetProperties();
    23 foreach (PropertyInfo property in properties)
    24 {
    25 Console.WriteLine("\tproperty.Name: " + property.Name + "\tproperty.MemberType: " + property.PropertyType);
    26 }
    27 }
    28
    29 public List<T> GetList<T>()
    30 {
    31 Console.WriteLine("Generate List for [{0}]", typeof(T).Name);
    32 return new List<T>()
    33 {
    34 Activator.CreateInstance<T>(),
    35 Activator.CreateInstance<T>()
    36 };
    37 }
    38 }

     

    • XMLTool<T>类
       1publicclass XMLTool<T>
      2 {
      3publicstaticvoid XmlSerialize_Save(List<T> needSerializedList, string xmlDirPath, string xmlFileName)
      4 {
      5 RootCollection<T> collection = new RootCollection<T>();
      6 collection.ItemList = needSerializedList;
      7if (!Directory.Exists(xmlDirPath))
      8 Directory.CreateDirectory(xmlDirPath);
      9using (System.IO.FileStream stream = new System.IO.FileStream(xmlFileName, System.IO.FileMode.Create))
      10 {
      11 System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(collection.GetType());
      12 serializer.Serialize(stream, collection);
      13 }
      14 }
      15 }
    • RootCollection<T>类:
       1     [Serializable]
      2 public class RootCollection<T>
      3 {
      4 public RootCollection()
      5 {
      6 itemList = new List<T>();
      7 }
      8
      9 private List<T> itemList;
      10
      11 public List<T> ItemList
      12 {
      13 get { return itemList; }
      14 set { itemList = value; }
      15 }
      16 }
  • MockClassLib工程:提供BaseEntityAppleCatPerson
    • BaseEntity类:抽象类,负责初始化类成员
       1     public abstract class BaseEntity
      2 {
      3 public BaseEntity()
      4 {
      5 InitiaWithNull();
      6 }
      7
      8 private void InitiaWithNull()
      9 {
      10 Type type = this.GetType();
      11 PropertyInfo[] properties = type.GetProperties();
      12 string[] PropNames = new string[properties.Length];
      13 Dictionary<string, PropertyInfo> PropNameToInfo = new Dictionary<string, PropertyInfo>();
      14 for (int i = 0; i < properties.Length; i++)
      15 {
      16 PropNames[i] = properties[i].Name;
      17 PropNameToInfo.Add(PropNames[i], properties[i]);
      18 }
      19
      20 foreach (string propname in PropNames)
      21 {
      22 string proptype = PropNameToInfo[propname].PropertyType.Name;
      23
      24 object value = null;
      25 if (NullValue.Keys.Contains(proptype))
      26 value = NullValue[proptype];
      27
      28 type.GetProperty(propname).SetValue(this, value, null);
      29 }
      30 }
      31
      32 private static readonly Dictionary<string, object> NullValue = new Dictionary<string, object>()
      33 {
      34 { "String", String.Empty },
      35 { "DateTime", DateTime.MinValue},
      36 { "Decimal", Decimal.MinValue}
      37 };
      38 }
    • AppleCatPerson类:测试类,继承于BaseEntity
       1     public class Apple : BaseEntity
      2 {
      3 public string Color { get; set; }
      4 }
      5
      6 public class Cat : BaseEntity
      7 {
      8 public string Type { get; set; }
      9 }
      10
      11 public class Person : BaseEntity
      12 {
      13 public int ID { get; set; }
      14 public string Name { get; set; }
      15 }

 

      Main工程的Program的Main方法中,一般情况下,调用Worker的泛型方法来处理测试类的话,可以写为:

      Worker worker = new Worker();

      worker.DoWork<Apple>();

      worker.DoWork<Cat>();

      worker.DoWork<Person>();

      但是,如果MockClassLib中需要处理的类型非常多时,这样显示调用必然是不灵活的,应当怎样向泛型方法DoWork<T>()的尖括号中动态传入类型呢?

      考虑代码:

            //Load assembly
Assembly mockAssembly = Assembly.LoadFrom("MockClassLibrary.dll");
Type[] typeArray = mockAssembly.GetTypes();

//Create instance of Worker
Worker worker = new Worker();
foreach(Type curType in typeArray)
{
worker.DoWork<curType>(); //Error
}

      可以看到,Type类型的实例是无法直接传入泛型方法的尖括号中的,T要求显式指明类型名。

      下面通过反射方式来获取泛型方法,并创建特定类型的泛型方法。

  • 对于非静态方法:public void DoWork<T>()

          对于非静态方法,调用MethodInfo.Invoke(object, object[])时,第一个参数需要指明泛型方法的所有者(即这里创建的worker对象),第二个参数为泛

          型方法的参数列表,DoWork<T>()没有输入参数,所以设为null

//Create an instance of Worker
Worker worker = new Worker();

//Get type of Worker
Type workerType = typeof(Worker);

//Get Generic Method
MethodInfo doWorkMethod = workerType.GetMethod("DoWork");

//Invoke DoWork<T> with different Type
foreach (Type curType in typeArray)
{
if (curType.IsClass && !curType.IsAbstract)//Filter BaseEntity
{
MethodInfo curMethod = doWorkMethod.MakeGenericMethod(curType);
curMethod.Invoke(worker, null);//Member method,use instance
}
}
  • 对于静态方法:public static void StaticDoWork<T>()

          不同于非静态方法,这里直接反射的类静态方法,所以Invoke()的第一个参数设为null

//Get type of Worker
Worker worker = new Worker();

//Get Generic Method
MethodInfo staticDoWorkMethod = workerType.GetMethod("StaticDoWork");

//Invoke StaticDoWork<T>
foreach (Type curType in typeArray)
{
if (curType.IsClass && !curType.IsAbstract)
{
MethodInfo curMethod = staticDoWorkMethod.MakeGenericMethod(curType);
curMethod.Invoke(null, null);//Static method
}
}
  • 对于有返回值的非静态方法:public List<T> GetList()

          如同动态调用DoWork<T>()方法一样,只是在处理返回值时,可以使用下面的方法

1 IList tempList = (IList)curMethod.Invoke(worker, null);
2 //Or
3 IEnumerable tempList = (IEnumerable)curMethod.Invoke(worker, null);
  • 对于泛型类:XMLTool<T>

          下面要使用泛型类XMLTool<T>的静态方法public static void XmlSerialize_Save(List<T> list, string dirPath, string fileName)方法。

          首先应通过反射构造出指定类型的泛型类XMLTool<T>,再反射出其中的XmlSerialize_Save方法并使用。

 1 //Use Generic Class
2 Type xmlToolType = typeof(XMLTool<>).MakeGenericType(curType);
3
4 //Get method
5 MethodInfo saveMethod = xmlToolType.GetMethod("XmlSerialize_Save");
6
7 //Invoke
8 saveMethod.Invoke
9 (
10 null, //Static method
11 new object[] { resultList, @"c:\", @"c:\Test_" + curType.Name + ".xml" }

12 );

 

       Program-->Main()方法的全部代码:

 1 namespace RetrieveUnknownClass
2 {
3 class Program
4 {
5 static void Main(string[] args)
6 {
7 //Load assembly
8 Assembly mockAssembly = Assembly.LoadFrom("MockClassLibrary.dll");
9 Type[] typeArray = mockAssembly.GetTypes();
10
11 //Create instance of Worker
12 Type workerType = typeof(Worker);
13 Worker worker = new Worker();
14
15 #region Member method
16
17 Console.WriteLine(">>>>>>>>>Use Generic Method:");
18 MethodInfo doWorkMethod = workerType.GetMethod("DoWork");
19
20 //Invoke DoWork<T>
21 foreach (Type curType in typeArray)
22 {
23 if (curType.IsClass && !curType.IsAbstract)
24 {
25 MethodInfo curMethod = doWorkMethod.MakeGenericMethod(curType);
26 curMethod.Invoke(worker, null);//Member method,use instance
27 }
28 }
29
30 #endregion
31
32 #region Static method
33
34 Console.WriteLine("\r\n>>>>>>>>>Use Static Generic Method:");
35 MethodInfo staticDoWorkMethod = workerType.GetMethod("StaticDoWork");
36
37 //Invoke StaticDoWork<T>
38 foreach (Type curType in typeArray)
39 {
40 if (curType.IsClass && !curType.IsAbstract)
41 {
42 MethodInfo curMethod = staticDoWorkMethod.MakeGenericMethod(curType);
43 curMethod.Invoke(null, null);//Static method
44 }
45 }
46
47 #endregion
48
49 #region Get A List & Serialize It to Xml File With Generic
50
51 Console.WriteLine("\r\n>>>>>>>>>Get List By Generic Method:");
52 MethodInfo getListMethod = workerType.GetMethod("GetList");
53
54 foreach (Type curType in typeArray)
55 {
56 if (curType.IsClass && !curType.IsAbstract)
57 {
58 MethodInfo curMethod = getListMethod.MakeGenericMethod(curType);
59 //Generate List
60 IList resultList = (IList)curMethod.Invoke(worker, null);
61 //Show List
62 ShowList(resultList);
63 //Use Generic Class
64 Type xmlToolType = typeof(XMLTool<>).MakeGenericType(curType);
65 MethodInfo saveMethod = xmlToolType.GetMethod("XmlSerialize_Save");
66
67 saveMethod.Invoke
68 (
69 null, //Static method
70 new object[] { resultList, @"c:\", @"c:\Test_" + curType.Name + ".xml" }
71 );
72 }
73 }
74
75 Console.WriteLine("Serialization Completed...\r\n");
76 #endregion
77 }
78
79 public static void ShowList(IList list)
80 {
81 Console.WriteLine("Type of list: {0}\r\nCount of current list: {1}\r\nType of item in list: {2}\r\n",
82 list.GetType(),
83 list.Count,
84 list[0].GetType());
85 }
86 }
87 }

 

       相关文章:

posted @ 2012-03-13 14:16 dotNET程序猿 阅读(179) 评论(0) 编辑
摘要: Download Source - 80KB原文作者:Qwertie, Canada博文主页:点击查看原文地址:点击查看免责说明:本文由CodeProject博文翻译而来,个人学习,仅供参考,欢迎指正,如有侵权,烦请告知删除。翻译原因:在WPF/Silverlight数据绑定流行的时代,很多开发者并没有深入研究WinForm所提供的数据绑定机制,以至于很多人在编写应用时,仍在后台代码中操纵数据集合,并不断重新加载到数据控件上。如果您和我一样,还在这么做,不妨读一下这篇文章,改变一下编码方式。详解Data Binding通过几个简单示例深入了解WinForm数据绑定特性简介: 关于WinFo..阅读全文
posted @ 2012-02-17 21:40 dotNET程序猿 阅读(1602) 评论(6) 编辑

这几天搭一个C/S的项目框架,发现一个以前没有注意过的问题,即:

在同一个解决方案(.sln)下的A工程(.csproj)引用B工程的.dll后,在代码中使用using是无法找到对应命名空间。

如图1所示,MCC.Client引用了MCC.Business工程生成的.dll,但在图2中,报了“Error 2 The type or namespace name 'UserProfile' could not be found (are you missing a using directive or an assembly reference?) C:\Documents and Settings\a531032\My Documents\visual studio 2010\Projects\MCC\MCC.Client\SysUtility\AppContext.cs 15 24 MCC.Client”的错误。

图1 解决方案结构

图2 编译错误

由于之前修改过工程名称,一直以为是这个原因造成的引用失败,便沿着一下方向查了一遍错误,最终找到了原因。

  • 查找被引用工程(此例中的MCC.Business工程)的Properties/Assembly.cs文件中AssemblyTitleAssemblyProduct是否有误?如图3所示。

图3 MCC.Business的Properties/Assembly.cs文件

  • 右键查看被引用工程(此例中的MCC.Business工程)的属性是否正确?如图4所示

图4 MCC.Business的属性页

  • 查找引用者工程的.csproj中的值是否与MCC.Business的Assembly信息一致?如图5所示

图5 MCC.Client的.csproj文件

  • 查看引用者工程的属性页,字段“Target Framework” 是否置为了“.NET Framework 4 Client Profile”?如图6所示

 图6 MCC.Client的属性页

问题找到了

     我的问题出在了创建MCC.Client工程(一个WinForm工程)时,VS 2010默认选择了“.NET Framework 4 Client Profile”,以便于在客户端部署时的便捷。但由于MCC.DataAccess工程中引用了System.Data.OracleClient(其并非包含在.NET Framework 4 Client Profile库中,而在.NET Framework 4 Full库中)。之后,MCC.Business引用了MCC.DataAccess生成的.dll,当MCC.Client去引用MCC.Business生成的.dll时,发现该.dll又引用了.NET Framework 4 Client Profile不包含的内容,所以在编译时MCC.Client对MCC.Business的.dll给出编译错误。

========================

.NET Framework 4 Client Profile 相对于 .NET Framework 4 的区别

  • 是后者的一个子集
  • 减少.NET Framework以及包还.NET Framework的应用程序的部署时间
  • 减少.NET Framework部署的失败
  • 减少.NET Framework在ISV软件的所占大小,从而给其软件更多的空间
  • 减少安装了.NET Framework Client Profile的系统受攻击的“界面”,因为Client Profille中部包括ASP.NET和一些服务器所要的组件
  • 从下图可以看到两者大小差异

来源于网络的一些参考博文:

个人学习,欢迎指正,仅供参考~

posted @ 2012-02-09 15:00 dotNET程序猿 阅读(454) 评论(1) 编辑

Download Source - 117KB

        如上述两图,左侧为WinForm的DataGridView,右侧为WPF的DataGrid(封装成了自定义控件DragDataGrid,通过WPF的ElementHost装载在WinForm中)。均可以通过左键拽取行进行拖拽排序。另外实现了从WinForm的DataGridView向WPF的DataGrid的拖拽,因此,两个DataGridView之间的拖拽和两个DataGrid的拖拽方法类似。以上控件均关闭了Sort功能,并将AllowDrop属性置为true.

  • WinForm DataGridView的行拖拽
    • 使用Drag & Drop系列方法通过e.Data.GetData()来传递拽取的行数据,TipPanel的移动显示在MouseMove中控制
  • WPF DataGrid的行拖拽
  • DataGridView 与 DataGrid之间的拖拽
    • 由于在WPF的DataGrid的DragEnter方法里,使用如下代码会报COM异常
    • 1 DataGridViewRow curRow = (DataGridViewRow)e.Data.GetData(typeof(DataGridViewRow));
      所以封装了一个数据序列化类DataSerializer将当前DataGridView 拖拽行的DataBoundItem序列化为string类型,在WPF中使用如下代码获取string后再反序列化为实例对象。
    • string strRow = (string)e.Data.GetData(DataFormats.StringFormat);
      Animal aimAnimal = (Animal)DataSerializer.DeserializeObject(strRow);
  • TipControl & Popup
    • 在WinForm中使用了一个TipControl的UserControl显示拖拽过程中的行信息
    • 在WPF中使用Popup显示当前行信息
  • 按住Ctrl键再拖拽行,则实现数据行赋值功能。
  • 存在的问题:还存在一些BUG和不足,个人学习,仅供参考。
posted @ 2012-02-06 16:33 dotNET程序猿 阅读(147) 评论(1) 编辑

Download Source - 123KB

  DataGridView是WinForm中非常灵活的一个控件,对于扩展其折叠功能的控件在网上已经有很多文章,但是只简要介绍了实现的方法,没有继续封装其他方法,比如数据绑定和增删功能,都需要在后置代码自己编写,加之复杂的业务逻辑,让代码显得冗余且不易复用。

  在前人的基础上,利用封装好的CollapseDataGridViewRow和CollapseDataGridViewRowCollection类,对CollapseDataGridView进行了功能扩展,新增了几个泛型方法和委托事件,尽量降低了控件逻辑与业务逻辑的耦合。

  新增了CollapseDataGridViewEventArgs事件参数,包含bool Result/执行结果,int RowIndex/影响的行号,string ErrorMessage/错误信息

  在CollapseDataGridViewRow类中增加了GroupTag属性,用于保存集合信息,Tag用于保存集合首行对应的条目实例

      在使用该控件前,需要定义三个类型,以代表团和运动员为例:

  • Athlete                 条目类
  • AthleteItemList : List<Athlete>     集合类,可以添加一些集合自有属性,用于保存条目的公共信息
  • AthleteGroupList : List<List<Athlete>>  集合列表类,调用控件BindDataSource<GL, T>(GL groupList) where GL : List<List<T>>方法时使用

       初始列表需要用户自己组织好AthleteGroupList列表,对控件进行数据绑定。将控件从左侧工具箱拖拽入设计区

      

      像使用一般的DataGridView一样,对控件进行DataPropertyName的设置,否则在使用默认数据绑定方法时无法绑定该数据行(自定义绑定方法除外)。此外SortMode属性设置为NotSortable,排序有点小复杂,还没动手做。。。 

    

  在CollapseDataGridView增加了如下几个属性,用于控制外观:

  

  完成以上设置就可以开始编写后台代码了。可以根据需要预先绑定几个事件,用于在列表数据发生变化时,处理业务逻辑。


  提供的事件如下:

  • OnBindDataDetail:数据绑定事件,在调用BindDataSource<GL, T>(GL groupList) 方法后,触发该事件,返回(object item/条目实例, int rowIndex/条目所在行号, bool isMainItem/条目是否为集合首行),可以根据三者条件编写绑定行Cell显示数据的逻辑。
  • AddGroupCompleted:新增集合事件,返回(object group/集合实例, CollapseDataGridViewEventArgs e/事件参数)
  • RemoveGroupCompleted:移除集合事件
  • AddItemCompleted:新增条目事件
  • RemoveItemCompleted:移除条目事件
  • OnDataCountChanged:集合或条目数量改变事件,可用于更新UI
            //注册行绑定事件 -- 可以去掉该行注释,使用自定义绑定行数据模式
//this.cdgvAthleteInfo.OnBindDataDetail += new CollapseDataGridView.BindDataDetailHandler(cdgvAthleteInfo_OnBindDataDetail);
//注册新增集合事件
this.cdgvAthleteInfo.AddGroupCompleted += new CollapseDataGridView.AddGroupHandler(cdgvAthleteInfo_AddGroupCompleted);
//注册删除集合事件
this.cdgvAthleteInfo.RemoveGroupCompleted += new CollapseDataGridView.RemoveGroupHandler(cdgvAthleteInfo_RemoveGroupCompleted);
//注册新增条目事件
this.cdgvAthleteInfo.AddItemCompleted += new CollapseDataGridView.AddItemHandler(cdgvAthleteInfo_AddItemCompleted);
//注册删除条目事件
this.cdgvAthleteInfo.RemoveItemCompleted += new CollapseDataGridView.RemoveItemHandler(cdgvAthleteInfo_RemoveItemCompleted);
//注册数据源数量变更事件
this.cdgvAthleteInfo.OnDataCountChanged += new CollapseDataGridView.DataCountChangedHandler(cdgvAthleteInfo_OnDataCountChanged);

  提供的公共接口如下:

  • 数据源绑定方法:void BindDataSource<GL, T>(GL groupList) where GL : List<List<T>>,GL为集合列表的类型,T为条目类型,如果用户没有注册OnBindDataDetail事件,则使用默认的数据绑定方式,CollapseDataGridView中每个集合的[0,0]位置显示分组标记的值,[i,0](i > 0)的位置不显示分组标记的值。该方法通过控件每列设置的DataPropertyName从提供的GL数据源中反射出相应的值,并绑定在Cell的Value中,没有反射到属性则绑定null。
  • 获取集合信息方法:G GetGroupInfo<G>(),G为集合类型,返回选中行所在集合的信息
  • 新增条目方法:void AddItem<G, T>(T item) where G : List<T>,G为集合类型,T为条目类型。之所以需要传入集合类型,是因为当传入null集合时或当前CollapseDataGridView为空,目标行将作为新的集合加入CollapseDataGridView中,则需要使用G反射获得其实例,绑定在GroupTag中,随后使用G GetGroupInfo<G>()方法时,才能由object转换成G类型,若以List<T>绑定在GroupTag中,取回时,G类型中的公共属性会丢失。
  • 插入条目方法:void InsertItem<G, T>(T item) where G : List<T>
  • 移除条目方法:void RemoveItem<T>(int itemIndex)
  • 新增集合方法:void AddGroup<G, T>(G group) where G : List<T>
  • 插入集合方法:void InsertGroup<G, T>(G group) where G : List<T>
  • 移除集合方法:void RemoveGroup(int itemIndex)

  以上方法都对应了上面提到的事件,可以获取相应的参数,进行一些业务逻辑的处理。

  不足和可能存在的Bug:

  • 异常处理尚未完善,可能存在未知的异常
  • 泛型的使用和部分代码冗余

  个人学习,欢迎指正,仅供参考

  参考文章:这里这里

posted @ 2011-08-18 19:55 dotNET程序猿 阅读(2946) 评论(17) 编辑
摘要: 在VS2008下封装WinForm自定义Loading控件。 AutoCircle.cs封装了旋转的圆形,直接在里面添加Label的话,计算圆形扇面的方法有点小复杂,所以在LoadingPanel.cs将AutoCircle和Label封装在一起。该控件中提供了当LoadingPanel状态变化时的事件public event RotateStateChangedHandler OnRotateStateChanged,当打开或关闭LoadingPanel时,可以用此事件来禁用/开启页面其他控件或做其他处理。 LoadingPanel暴露了几个属性可以对AutoCircle进行外观的设置 1.阅读全文
posted @ 2011-08-16 15:36 dotNET程序猿 阅读(755) 评论(2) 编辑
摘要: “foo” 和“foobar”等单词经常会作为示例名称,出现在各种程序和技术文档中。据统计,在各种计算机和通信技术文档中,大约有百分之七的文档出现了这些词 语。可是这些文件都没有为它们给出合适的解释。虽然这不是个大问题,但对于初学者,尤其是母语非英语的人来说,这些单词往往会带来不小的迷惑。本文就介绍 一下这些单词的含义和来历。 虽然正式文件中对于“foo”的语源没有详细的记载,但我们仍可以从它的发展历史中,捋清一些脉络。 “foo” 一词最早出现在一些二战前的漫画和卡通作品中。在关于消防队员的漫画“Smokey Stover”中,作者Bill Holman大量的使用了“foo”一词。这部漫画.阅读全文
posted @ 2011-05-27 10:39 dotNET程序猿 阅读(314) 评论(0) 编辑
摘要: 一、态度决定一切1、最高优先级应该是解决问题,而不是寻找罪魁祸首。指责不能修复Bug。2、欲速则不达:要投入时间和精力保持代码的整洁、敞亮。在不深入了解真正的问题以及可能的后果,就快速修改代码,这样只是解决表面问题,最终会引发大问题。3、对事不对人:不带个人情绪并不是盲目地接受所有的观点,用合适的词和理由去解释为什么不赞同。不要谴责,没有评判,只要简单表达自己的观点。因为负面的评论会扼杀创新。4、排除万难,奋勇前进:重构低质量代码或许需要很大勇气,但是如果你对此妥协,那么问题就会进一步恶化下去。在没有理解代码时,不要轻易地否定和重写它们。那不是勇气,而是鲁莽。二、学无止境:既要学习新技术、新方阅读全文
posted @ 2011-05-23 09:11 dotNET程序猿 阅读(338) 评论(0) 编辑
摘要: 项目继续进行中,在做人员管理模块时,遇到了工作人员可能重名的情况,如果多绑定几列来显示人员的区分信息,显得页面冗杂。就想到了用ToolTipService来显示一些区分信息,当用户的鼠标悬停到某行数据时,显示该行数据的一些详细信息。  从数据库中取出的人员信息的实例都放在一个List<T>中,在后台代码将之赋给ListBox的ItemsSource,前台进行数据绑定。最终呈现效果如下:...阅读全文
posted @ 2010-09-19 15:02 dotNET程序猿 阅读(898) 评论(3) 编辑
摘要: 前段项目中遇到了用户图片上传问题,Silverlight仅支持jpg和png格式,无法满足用户对BMP和GIF格式上传的支持。再者就是需要在在客户端将图片转为byte[]格式,之后传回服务器并保存到SQL Server 2005中image类型的字段,查看了网上很多资料和风云的《银光志》,给出的方法不大适合当前项目的要求,所以综合大家的方法,支持了BMP图片格式,和客户端转化数据流的方法(没有支持...阅读全文
posted @ 2010-09-11 21:54 dotNET程序猿 阅读(1365) 评论(3) 编辑