YAXLib---- XML序列化神器

今天早上翻译了Yet-Another-XML-Serialization-Library-for-the-NET,刚开始以为很短。翻译着发现不对。。然后你不逼你自己。怎么知道自己做不到。于是。将近4个小时把30页的文档翻译完了。因为文章很长。所以本文只列出前两部分。我把翻译好的做成了pdf, 文档下载:XML序列化神器 1 介绍 在本文中,会把要提到的XML序列化库叫做YAXLib,我们知道。.Net 还是提供了一些序列化功能的,尤其是XmlSerializer,该类被程序员广泛使用用来序列化对象成XML,当然,反序列化也是可以的。我认为XmlSerializer类的问题有几下几点 程序员不能自由的选择生成的xml的结构 不支持序列化一些集合类,比如Dictionary<,> 或者IEnumerable<>的属性 当反序列化的时候,如果缺失了一些域,则反序列化失败,这就使得用来存储一ixekeyi被用户编辑的配置文件变得不合适了。 2 为什么使用YAXLib YAXLib解决上述问题的特点 程序员可以决定xml文件的结构,一个属性可以是一个子元素,或者是其他属性的属性,或者是一个在类中没有对应属性的元素。 集合类也可以被序列化成一个逗号分隔(也可以是其他任何分隔符)的数据项列表,而且。为Dictionary<,>对象实现了一些特殊的格式化功能,这样,使得程序员可以完全控制生成的xml文件的结构 他支持System.Collections.Generic 命名空间中的所有泛型集合类(像Dictionary, HashSet, LinkedList, List, Queue,SortedDictionary, SortedList, 和 Stack) 和在System.Collections 命名空间中的非泛型集合类( ArrayList, BitArray, Hashtable, Queue, SortedList, 和 Stack)非泛型集合类可以包含多种不同的对象,而且,库还支持序列化和反序列化一维,多维,不规则的数组。 支持通过对基类/接口的引用,实现对一些对象集合的序列化和反序列化。 支持多级反序列化 程序员可以为生成的xml提供注释 当进行反序列化的时候,程序员可以选择性对于那些与类的属性相关,但没有出现在xml文件中的数据应该如何处理。这种情况下可以看错是一个错误,然后类库抛出一些异常,或者记录错误,或者可以被看成一个警告,然后用程序员预定义的值赋给对应的属性,而且,程序可以可以选择忽略这个问题,相关的异常将既不抛出也不作任何记录。请查看保留空引用标识那一节 看看什么时候可以忽略孤立的数据也许对你有帮助 程序员可以自己选择错误处理规则,对于数据敏感的应用程序,程序员可以选择在任何异常的情况下,库都应该抛出并且记录异常,对于其他的一些情况(比如要求不那么高的配置文件的存储),程序员可以选择把异常仅仅看成一个警告,仅仅记录一下,让程序的其他部分继续运行。 文档下载:XML序列化神器 著作权声明:本文由http://leaver.me 翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

关于源代码控制的五个误区

上周,在Red Gate好朋友的帮助下。我发起了一个名为小竞赛赢得优秀的SQL Source Control 5份授权的活动。参加的方式很简单-分享你使用源代码控制过程中,本可以避免的最痛苦的经历 许多痛苦的故事都出现了。但是我认为这五个获奖者的故事值得分享,并且我都做了评论,因为我觉得随着时间的流逝,这些故事依然对我们有所启发。那么,开始享受这些故事吧,我希望这些知识中的闪光点能够帮助你以后不会掉进相同的陷阱里。 给获奖者:希望那些授权可以帮助抚慰你们关于那些已经过去的痛苦记忆。不久我会联系你们关于奖项颁发的相关事宜。  1.通过Ctrl-Z来进行源代码控制 第一个故事来自 courtesy of MyChickenNinja ,仅仅文字就看得我头疼。在这个特殊的故事里。应用程序被前员工破坏了。。这非常头疼。但是至少还是有很多方法可以恢复代码的。如果不要求数据的话。。 第一个问题是备份,最近的备份已经是3周前的。这绝对是一个教训—你的环境真的备份了吗?一会我会在另一个故事里简单的再说到这个问题。故事的核心部分是通过Ctrl-Z来进行伪源代码控制 他们运行他们的代码,并且不断地更新,也包括开发环境,并且使用Ctrl-Z来撤销坏的改变 好吧。这实在令人难以置信-如果你的应用程序已经做了一些编辑。然后被关闭了。怎么办?或者PC关机了?等等—他还说他们在哪写代码,哪儿就是开发环境?记住!撤销不是源代码控制!  2。多个数据库和集成问题 第二个故事来自Brandon Thompson,他极度不开心,因为他工作在一个有着很多数据库源的环境里,并且,这些数据库都在正在进行的开发项目下面,数据库集成非常困难,这就意味着处理多个数据库备份可能还有个在海外。。 我们的开发团队在海外,因为他们有他们自己的数据库集,这些数据库我从没看到过。但是他们会把改变的文件发给我们来适应我们的开发环境 我发现最痛苦的是简单重复的手工劳动仅仅是使得大家能够协同的更好。这是没有一点创新并且没有任何增值的行为,比如增加新的特性,这就导致除了干这些。没什么时间真正在写代码了。 源代码控制是为了能够保证团队之间平稳尽量无摩擦的一起工作。它是项目的一个润滑剂,和持续集成开发还有自动部署都属于同一类。这些都是软件开发中的“面包和黄油”,是任何成功团队编写代码的基础。  3. 依赖未测试的备份 下一个是Barry Anderson,他写了一个我们都曾经经历过的痛苦:不能从备份恢复了!事实上在Barry的故事里。几个月都没备份了。之前备份本身还是坏的。这太糟糕了。但是,对于那些依赖备份的人来说这是一个严重的疏忽。 当然对于这个疏忽也有自己的借口。Barry解释道: 我们的经理(不是存储团队的)后来告诉我们既没时间也没空间来测试备份了。。。 备份是一件很重要的事情。但从备份可以恢复也是同等重要,我最近在配置大量的新环境的时候,备份本应该发生的但是就是没有发生。只有当我坚持要进行恢复测试的时候,问题才浮出水面,对于很多人来说。只有当他们真的需要从一系列的数据丢失中恢复数据的时候,才发现不能恢复了。。测试你的备份,恢复他们,不要相信任何人的说辞.  4.人工合并工具 来自Graham Sutherland的故事讲了一个人来做机器工作的故事 我们有一些开发人员,每一个在他们的硬盘上的都有整个项目的一个副本,每一次一个改变发生的时候,我们就会下载技术老大改变的源代码,然后使用diff工具来查看改变。然后手工更新他们。一行一行。。全靠双手。。 这个故事比听起来还要不可思议,在源代码控制工具出现以前这确实是存在的。一个海外开发团队成员就是这样干的。随后他们这样解释:带头的开发者需要在提交前检查其他开发人员的工作进度。 这确实是类似于之前的观点,在有多个数据库集成的情况下;我们有技术来解决这些问题!每当一个人在软件开发中从事任何劳动密集型,重复的过程,你真的不得不停下来问:“有没有更好的方法?”通常是有的。  5.剪切和粘贴版本控制 Robin Vessey 让我产生了共鸣,因为它真的是伪VCS(Version Control System)最普遍的方式。剪切或者复制,然后粘贴到新的位置,通过这种方式会包含重复的目录或者文件。因此一般这些文件会被以日期或者其他标识符来标识时间帧。 在Robin的故事里,他打算通过网络移动一个目录结构。 他很简单但高效,我剪贴然后粘贴了一个完整的目录树,任何东西,通过网络发送。但这些文件留在了我这一边。却没有到达另一边。我仍然不知道为什么。 我必须承认,我对任何剪切和粘贴文件的操作的态度是非常谨慎的,因为我看到这种情况在一个本地文件系统中发生了很多次,更不用说通过网络了,在上面的的Robin的故事,就是没有备份被恢复,因为他们一段时间后会停止备份,“因为我们没有更多的空间”。是不是感觉好像和前面某一方法很像。。  总结 工作在一个没有源代码控制的环境下是很可怕的。现在就停止吧。伙计们,我们是很优秀,但在在源代码控制下工作是很专业的。并且现在有很多的VCS产品。托管服务,集成工具,真心是没有任何理由不把代码-包括数据库,部署在源代码控制下。  原文地址:5-ways-to-do-source-control-really 著作权声明:本文由http://leaver.me 翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

简单扩展方法增强代码可读性

本文技术含量不高,但是思路可以借鉴。。 介绍 当你处理计时器,时间间隔,或是其他关于日期的计算的时候。你必然会使用TimeSpan类。 我觉得写出下面的代码可读性并不好。。 而下面的代码就要好一些 ** 扩展方法** 使用这些扩展了int类的方法。可以使得创建TimeSpan可读性更好 许可 本文所有源代码包括文件在CPOL下授权。。 原文地址:Simple-extension-methods-for-code-readability 著作权声明:本文由http://leaver.me 翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!    

11个高效的VS调试技巧

介绍 调试是软件开发周期中的一个很重要的部分,有时很有挑战性,有时候则让程序员迷惑,有时候让程序员发疯,但是。可以肯定的是,对于任何不是太那个微不足道的程序来说,调试是不可避免的。近年来,调试工具的发展已经使得很多调试任务简单省时了。 本文总结了十个调试技巧,当你使用VS的时候可以节省你很多时间。 1. 悬停鼠标查看表达式 调试有时候很有挑战性,当你步入一个函数想看看哪块出错的时候,查看调用栈来想想值是从哪来的。另一些情况下,则需要添加一些监视表达式,或者查看局部变量列表,这通常还是花费一些时间的,但是。如果你把你鼠标指向你感兴趣的一个变量。你会发现事情简单多了。而且,类和结构体可以通过单击展开。这样。你就可以方便快捷的找到你想查看的变量了。 2. 实时改变值 调试器不仅仅是一个分析程序崩溃或是异常结果的工具了,许多bug都可以通过步入新写的函数,检查函数是否如期望的那样运行来预防。有时候你可能会好奇“如果条件为真函数会正确运行吗”大多数情况下,根本不需要改变代码重启挑起,仅仅把鼠标悬停到一个变量上,双击值然后输入一个新值就可以了。。 3.设置下一条语句 一个典型的调试情况就是通过单步跟踪分析为什么一个函数调用失败了。当你发现一个函数调用的另一个函数返回错误的时候你会怎么做?重启调试?有更好的方法。拖动这个黄色的语句标识到你想下一步执行的语句前就可以了。比如你刚才失败的那块,然后步入。简单,不是吗? 4.编辑然后继续 调试一个复杂的程序,或是一个插件的时候,在一个被调用很多次的函数处发现一个错误。但是不想浪费时间停下来,重新编译然后重新调试。没问题,仅仅在该处改正代码然后继续单步就可以。VS会修正程序然后继续调试不需要重启 注意,编辑然后继续有大量的已知限制,首先,64位代码是不行的。如果他如果为你的C#程序工作。就去工程设置的生成选项,然后目标平台为x86.不要担心。发布版的目标平台和调试的时候是分开的。可以被设置为任何平台。。 第二.编辑然后继续改变在一个方法里应该是局部的。。如果你改变了方法签名,添加一些新方法或是类。你就不得不重启程序了。或者撤销改变来继续。改变方法也包含lambda表达式隐式修改的自动生成的代理类,因此也不能继续。 5.方便的监视窗口 大概现代的调试器都有一个监视窗口,无论如何。VS允许你简单的添加或移除变量。单击空行,输入你的表达式按下回车,或者是在不需要的表达式上按下Delete键就可以删除了。 而且。从监视窗口你不仅仅可以看到“正常”的变量。你可以输入$handles 来追踪你的程序打开了多少句柄(可以方便的修复内存泄漏) ,输入$err 可以看到上一个函数的错误码,然后使用工具-错误信息可以看到更详细的描述,或者输入@eax(64位是@rax)来查看包含函数返回值的寄存器。 6.带注释的反汇编 使用交互式的反汇编模式可以使得优化程序的关键部分变得很容易,VS给出对应你代码每一行的汇编指令,并且运行单步运行。同时,可以在任何位置设置断点。而且,表达式的查看和修改也像在C++代码里一样 7.带有栈的线程窗口 调试多线程的程序是痛苦的。。或者也可以是很有趣的。取决于你的调试器。VS2010真正优美的特性是线程窗口的栈视图,通过窗口的调用栈你可以方便的总览线程。 8.条件断点 如果你尝试通过断点再现一个罕见的事件,该情况引发了一些严重的错误。你可以添加条件断点。定义一个断点的条件,然后如果条件不成立,VS会忽略该断点 9.内存窗口 有些bug由不正确的结构体定义引起,忽略的对齐属性等等。查看内存中的内容可以定位然后修复bug。VS提供了一个放百年的内存窗口,可以把值以8/16/32/64位的形式展示。还有浮点值。也允许实时改变他们。就像在文本编辑器里一样。 10.转到定义 这个特性不是直接关于调试的,而是关于浏览大项目的。如果你尝试找到一些不是你自己写的代码中的错误,快速知道“这个类型是什么”或者“这个函数是干嘛的”,可以节省很多时间,VS通过一个转到定义命令方便了你。 11.命令窗口 第十一的技巧chaau已经建议过了。确实可以节省很多时间,VS支持命令窗口,可以通过,视图-其他窗口-命令窗口来启动。一旦激活,你可以输入不同的命令来自动化调试。举个例子。你可以通过如下命令 简单的模拟MFC COleDateTime 变量。 许可 本文包括源代码和文件在CPOL下授权。  原文地址:10plus-powerful-debugging-tricks-with-Visual-Studi 著作权声明:本文由http://leaver.me 翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

C#编写文件搜索器

介绍 在装有Vista的机器上。我想通过一个给定的字符串来搜索我硬盘上的一个文件,该文件内容包含这个字符串序列,资源管理器是做不到的。因此,我就决定自己写吧。然后就写成这样了。。 我做了什么 你必须输入一个选择一个搜索目录,这样程序才知道在哪搜索文件/目录,如果你选上了“包含子目录”复选框,程序就会递归地搜索指定目录的子目录,指定的文件名可以是像 “.wav;.mp3;Christma??ree.*” 这样的字符串,程序将会列出所有的文件/目录匹配这些文件名 你也可以使用一些限制条件来限制找到的项目,每一个限制条件可以通过选上复选框来激活,限制条件的参数可以在右边选中就行了。 1. “Files newer than”将会列出LastWriteTime(上次修改时间)晚于指定时间的文件 2. “Files newer than”将会列出LastWriteTime(上次修改时间)早于指定时间的文件 3. “Files containing the string"仅仅列出包含字符串参数的文件。 程序将会把字符串转换成字节序列,可以使用ASCII或者Unicode编码,取决于你的选择,然后搜索每一个出现这个字节序列的文件。 点击Start(开始)按钮就开始搜索了。找到的项目会列在下面,如果搜索时间太长了。你可以点击Stop(停止)来停止搜索。 如果你双击下面的一个文件。不是文件夹哦,程序将会根据关联程序打开该文件 如果你邮件一个项目,然后选择“Open Containing Folder”(打开包含文件夹)将会在资源管理器里打开包含该项目的文件夹 如果你想要把搜索结果保存到一个文本文件。输入个分隔符分隔项目,然后点击“Write results to text file…”(保存结果到文本…) 使用代码 1. MainWindow处理所有的界面事务 2. Searcher类提供了业务逻辑,用来搜索FileSystemInfo对象 当用户点击Start(开始)按钮,Searcher.Start 方法就会执行,该方法开启了一个名为SearchThread 的新线程,这个线程搜索文件/目录,匹配用户输入的参数,如果找到了一个匹配的FileSystemInfo对象,它就出发一个异步的FoundInfo 事件,然后MainWindow就可以从FoundInfoEventArgs中解出FileSystemInfo对象,然后更新结果列表,当线程结束的时候,将m_thread成员对象设置为null,每一次Searcher.Start 执行的时候都会检测m_thread是否为null,因此同时不会有两个线程在运行。 当用户点击Stop(停止)按钮的时候Searcher.Stop 方法被执行,然后设置m_stop 成员为true, Searchthread会注意到这个改变。注意本操作是线程安全的。因为布尔变量只需要一步就操作完成了 重要:在Searcher_FoundInfo 事件处理中,MainWindow使用Invoke方法通过代理来调用this_FoundInfo 方法。通过这个方法,MainWindow是的更新结果列表的代码在MainWindow的线程里执行,而不是在Searcher的线程里,直接调用this_FoundInfo 方法会引发程序崩溃,因为Searcher_FoundInfo 事件处理和图形界面控件不同步。 CreateResultsListItem 方法创建并添加一个ListViewItem 到结果列表中,然后展示FilesystemInfo 对象包含的数据,FileSystemInfo 可以是FileInfo 或是DirectoryInfo ,取决于Searcher 找到的结果, is操作符可以用来判断对象的类型,如果是FileInfo独享,列表还会以KB为单位显示文件大小 当Searcher 线程结束的时候,触发ThreadEnded 事件,因此,MainWindow可以注意到搜索结束,Searcher_ThreadEnded 事件处理句柄使用和Searcher_FoundInfo一样的方式调用Invoke方法。 Demo下载 FileSearcher 许可 本文包括源代码和文件在CPOL下授权 原文地址:File-Searcher-in-C 著作权声明:本文由http://leaver.me 翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

CSV导入导出工具

介绍 本文介绍并且实现了在平面文件CSV和SQL server之间的导入导出功能。使用VS2005写的。使用了.net 2.0 本文基于前一篇文章:从CSV导入数据并存储到数据库,本文包含了新功能,比如,导出功能,在数据库创建表,批量拷贝。接下来的例子中有很多注释。 导入 通过ODBC驱动连接到一个CSV文件,然后把文件读到一张表了(基于前面提到的那篇文章) 使用不同的编码和不同的行分隔符(基于前文) 加载CSV文件到DataSet(基于前文) 如何显示对CSV文件的预览(基于前文) 通过SqlBulkCopy的对象向SQL server转移数据,原始数据是DataSet实例 使用结构表,基于CSV文件,创建一个新表 使用事件来处理批量拷贝的进程 导出 浏览SQL 数据库中的用户表 使用不同的编码和分隔符 使用SqlDataReader读取数据,使用StreamWriter转移数据到平面文件 使用 下载工程 新建一个数据库,或者使用一个存在的数据库 修改软件中的数据库连接字符串,在prop.cs文件中 运行工程 一些代码段 加载CSV到DataSet中 通过SqlBulkCopy从ODBC连接中转移数据到数据库 基于结构表创建表 获取数据库中用户表名 通过StreamWriter写数据 Demo下载 CSV_import_export 许可 本文包括源代码和文件在CPOL下授权 原文地址:C-CSV-Import-Export

ListView布局管理器

介绍 使用ListViewLayoutManager 可以控制ListView/GridView列的布局 固定列宽:有着固定列宽的列 范围列宽:有着最小最大宽度的列 比例列宽:成比例的列宽 范围列宽可以限制列的宽度,也包括填充列的剩余可视区域。 据我们了解的Html中的表格和Grid空间。比例列以一个百分比来定义列宽,以下几个因素共同确定了比例列的宽度。 垂直ListView滚动条的可视与否 ListView控件宽度的改变 非比例列宽度的改变 本程序支持通过XAML或是后台代码来控制ListView。如果通过XAML来控制。则允许ListViewLayoutManager 被附加到一个存在的ListView控件上。 ConverterGridColumn 类通过接口IValueConverter 提供了对象绑定。使用ImageGridViewColumn 类则允许通过DataTemplate(数据模板)将列显示成图片等。 在 User Setting Applied中,我展示了如何固定ListViewlieder顺序和大小 XAML中ListView/GridView布局 固定列 下面的例子展示了通过XAML使用固定列宽控制列 设置附加到ListView控件上的ListViewLayoutManager 的Enabled属性为True。然后FixedColumn.Width 就会阻止鼠标拖动改变列的宽度。 比例列 下面的例子展示了使用XAML通过比例来控制列 对比Grid控件的RowDefinition.Width 属性,ProportionalColumn.Width会计算百分比。简单来说,就是上面的例子中Name列会占到总宽度的25%,而City列占到75%。 与固定列相似。鼠标将不能改变列的宽度。 范围列 下面的例子展示了使用XAML通过最小/最小宽度来控制列 第一个范围列的IsFillColumn 属性被设置为True,因此将会自动改变大小来填满剩余的空间,而如果ListView包含一个比例列的话,范围列将不会填充 通过鼠标可以拖动范围列的宽度。鼠标指针会有一些提示。。 组合使用 在真实的世界里。组合使用很普遍。他们的顺序可以多种多样。 使用后台代码控制ListView/GridView布局 定制列的效果 类ConverterGridColumn 作为一个基类,用来绑定列到独立的对象。 列以图片展示 ImageGridColumn 作为一个基类,用来绑定列到图片 有意思的地方 作为ListView控件的核心部件- ListViewLayoutManager 有以下的功能 阻止改变固定列和比例列的宽度 强制了范围列的范围 随着ListView控件的改变而更新列布局 随着某一列的改变而更新布局 为了正确的接收到请求的信息,分析ListView控件的可视树是很有必要的,Thumb对象提供了列宽改变的事件。而为了正确的展示鼠标指针,PreviewMouseMove 和PreviewMouseLeftButtonDown 事件都会被处理 当Viewport控件大小改变(ScrollChangedEventArgs.ViewportWidthChange)的时候,会触发ScrollViewer 控件的ScrollChanged 事件 通过使用DependencyPropertyDescriptor 可以追踪 GridViewColumn的宽度改变。并发出通知。 为了可以集成进已有的系统,列数据被放置在附加属性里。使用DependencyProperty.ReadLocalValue()方法会检测当前的属性是否在同一个对象里。 类ConverterGridViewColumn 同时使用一个简单的绑定。展示数据转换(IValueConverter接口) 类ImageGridViewColumn 在数据模板中使用FrameworkElementFactory 来动态嵌入图片,缺省情况下,在ListView/GridView控件中的图片会自动拉伸(Image.Stretch属性),因为数据模板中的图片是动态创建的。模板元素的值需要使用绑定来制定 许可 本文及所有代码和文件在CPOL下授权 Demo下载 ListView LayOut 原文地址:ListView-Layout-Manager 著作权声明:本文由http://leaver.me 翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

从数据库读取图片发生“无效的参数”异常

介绍 我发现对于很多人来说,当从数据库里载入一张图片然后重新创建成一张图片显示的话会有这样一个问题—-当他们尝试重新创建新的图片的时候,会抛出一个“无效的参数”异常 因此,本文介绍该异常如何产生。并且我希望未来当我或是你发生这个错误的时候还能有所帮助。。 背景 存储图片到数据库里面是一个很有效的想法。很多人在一些场合都会这样做。的确,这是一个很好的想法。在图片很小的情况下,或者图片不是太多。在这两种情况下,当你需要图片的时候,你会实时去加载它们。而当你不需要的时候如果从数据库里加载图片会浪费很多带宽。并使得你的程序有一些慢。 但问题是这种方法也很容易发生错误。–尤其是你使用字符串连接,然后组合到你的SQL语句里面—并且这个错误只有当你打算使用存储的信息的时候才会发生。然后,看起来似乎是你的读取代码写错了—不可能—它是正常的。我在其他地方都可以的。。 从数据库里加载图片 重数据库里读取一张图片然后转换成图片显示是很简单的。 但是-如果data因为一些原因不是有效的图片,那么这一行 将会抛出一个异常—无效的参数 只有当你真正看了从数据库里返回到data里的数据-而不是简单的瞄了一眼调试器,你才能注意到是什么原因。。 它看起来不像是错的,所以它可能就是你想要的。-虽然21字节是一个很大的线索:你的图片可能只有21字节长?那图片可真小。。 但是,上面的是可以读懂的。。稍微练习一下。。每个字节是一个ASCII码。。 简而言之,你从数据库里得到的数据是一个人类可以读懂的字符串,意思是是 当这个Image类试图把它转换成一个图片的时候,必然是不可能的。抛出异常就是必然的了。。代码是正确的。data才是问题所在。 保存图片到数据库 这才是引发问题的地方。 通常。这是因为把字符串连接起来构造SQL语句引起的。 不要在SQL语句中包含image对象—它会调用Image的ToString方法。而这个方法会返回 因此你的上一条语句其实就相当于 存储并不会有什么问题—但是事实上只是把Image的类型名保存了。而你傻傻的以为是图片数据本身。 这还不是唯一的一个不让你直接连接字符串构造SQL语句的原因,如果你想知道其他原因。 使用Google 搜索Bobby Tables,—这不是闹着玩的。。 好了。其实把代码写正确也不难,虽然可能得多花一些时间。但是,它可以帮助提高代码的可读性和可靠性。而你要做的就是使用一个参数化的查询。 首先,把图片转换到一个字节数组里。 然后在SqlCommand对象里使用这些字节 结束之前 不。。你不能取回那些你已经错误的存在数据库的信息。。所以。。全部删掉把。然后重新存一遍。 许可 本文包括代码和源文件,在CPOL下授权  原文地址:Why-do-I-get-a-Parameter-is-not-valid-exception-wh 著作权声明:本文由http://leaver.me 翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

JavaCC入门教程及相关资源

今天下午翻译了一篇简单的文章后。就去看JavaCC的东西了。。然后就找到了一篇入门教程 然后之前我是找到了一篇翻译过来的的某熊的战略储备基地 从头到尾读了一遍英文的。感觉还是英文的写的要好一些。建议对照着翻译看英文。JavaCC也就那么回事。。 同时在在这目测百慕大群岛的什么工程与应用科学学院找到了一些其他的文档。其中一篇是JavaCC-FAQ很好。基本上有关JavaCC的问题都有解释。 在FAQ里,看到了一个关于JJTree的介绍,写的不错。建议看看。 还有一个是国外某学校的编译原理课程的ppt下载,好象是以JavaCC作为工具的。还没认真看。 还有一篇JavaCC 研究与应用 ,写的平常。不过是中文版的。 最后。千万不要忘了官方文档。也包括你下载的JavaCC里面的Demo。。

C#使用Graphics创建饼图

介绍 这个程序是使用C#中的Graphics来创建一个饼图的,我已经尽我所能写的很好了。如果你有任何建议可以分享给我,这样我也能从中学习。 使用代码 最近我迷上了Graphics类。我仅仅体验了一下Graphics的DrawPie() 和FillPie() 方法。 最为一个简单的Demo,我创建一个有着五个文本框的窗体,一个按钮,一个图片框。一会我就把饼图画在图片框里 在创建一个饼图之前,我们头脑里要有这个意识。我们不能创建一个不符合常规的圆,创建圆我们需要度数信息。 为了转换度数。我们首先把给定的值做个求和。然后得出文本框里所有值的和。然后呢。用每个值除以总值再乘以360度。 代码如下: 值转换完毕后。我们可以创建Graphics类的实例了。 然后我们需要创建一个矩形区域,在这个矩形区域里绘制饼图。 前两个参数定义了矩形左上角的坐标,后两个分别定义了举行的宽和高。 为了能够比较清晰的看出饼图各部分的比例。我们需要创建五个笔刷。 现在我们可以开始创建我们的饼图了。graphics.FillPie();方法接受四个参数 笔刷,用来填充扇形 矩形:饼图将被创建的区域。 开始角度:饼部分的开始角度 覆盖角度:饼部分扫过的角度 一般来说graphics.FillPie();方法并不是创建一个完全的饼图,而是创建饼图的一个扇形部分,我们会创建一系列的扇形最终看起来像是一个饼图。 上面代码的第一行将会创建第一个红色的扇形。起点是0度,并且创建一个计算好的扇面。 之后,在第二行,我们的扇面的起点就会接着上一步的结束的位置,也就是deg1 ,第二行,我们的起点就会是 deg1+deg2 这段代码如你所见,可能不是最优的。我们创建了五个不同的笔刷。和不同的浮点数,而这些操作可以用循环完成。。 我故意没有这样做。因为,这样做了就可能使问题复杂化。下面是使用循环和数组完成相同的工作。 首先我创建一个整型数组,数组元素个数等于列表框里的数目。然后我使用一个循环计算了所有值的和。 然后。我创建了一个颜色的数组,这里我建议不要创建一个多于6个扇形。。不然看起来就连在一起了。。 第三步呢。。我再次使用循环去把值转换成度数。fDegValue 用来保存每次计算的度数。在我们前面的例子里。我们需要把前面几个值加起来作为下一个扇形的开始。而这里。我们使用fDegSum 来保存前面的和就很好了。 本文很简单,也就使用Graphics创建一个饼图而已。如果是要创建一些专业的图表就要用到.net提供的图表控件了。 下载:源代码和Demo 原文地址:Create-Pie-Chart-Using-Graphics-in-Csharp-NET 著作权声明:本文由http://leaver.me 翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!