
2008年10月10日
ASP.NET学习笔记系列:
ASP.NET 2.0 提供了非常强大的绑定能力,而 ASP.NET 2.0 新增的 GridView 控件更是充分体现和发挥了数据绑定强大的功能。GridView 的数据绑定和页面显示可以通过简单的代码实现,大大提高了开发效率。
不过有个地方让人不爽,就是在使用分页时,如果绑定的数据不满一页,那么 GridView 仅显示绑定的数据。例如,将 GridView 的 PageSize 设置为 10,每页显示 10 条数据,如果当前查询仅返回了 6 条数据,那么 GridView 就显示这 6 条数据,如果当前查询返回了多于 10 条数据,那么 GridView 则显示 10 条数据,这样当执行不同的查询时,GridView 时而显示 10 条数据,时而显示 1、2、3、……,9 条数据,GridView 的显示区域随着绑定的数据条数的变化而变化,给人很糟糕的交互体验。
怎么办?如果能够不管绑定的数据条数是多是少,都能始终显示相同的行数就好了,也就是说,当 GridView 绑定的数据条数不满一页时,通过某种方法在 GridView 中添加空行,使 GridView 能够始终显示 PageSize 设置的行数。
那么怎样添加空白行呢?还是利用 GridView 的 DataBound 事件,在绑定结束后,通过判断 GridView 的 Rows 属性将行数补充到和 PageSize 设置的大小一样,具体代码和效果如下:
public void gridView_DataBound(object sender, EventArgs e)
{
if (gridView.Rows.Count != 0 && gridView.Rows.Count != gridView.PageSize)
{
Control table = gridView.Controls[0];
if (table != null)
{
for (int i = 0; i < gridView.PageSize - gridView.Rows.Count; i++)
{
int rowIndex = gridView.Rows.Count + i + 1;
GridViewRow row = new GridViewRow(rowIndex, -1, DataControlRowType.Separator, DataControlRowState.Normal);
row.CssClass = (rowIndex % 2 == 0) ? "alternate" : "item";
for (int j = 0; j < gridView.Columns.Count; j++)
{
TableCell cell = new TableCell();
cell.Text = " ";
row.Controls.Add(cell);
}
table.Controls.AddAt(rowIndex, row);
}
}
}
}
需要注意到是:
1. 添加的 GridViewRow 的 RowType 需要设置成 Seperator;
2. 设置空白行内地 TableCell 属性时,应注意 GridView 对应列的 Visible 属性是否设置为 false,和 GridView 的 AutoGenerateCollomn 是否设置为 true,如果是,那么应该对应的做一些处理。
最后的填充了空白行的 GridView 效果如图:
posted @
2008-10-10 14:23 zsi 阅读(159) |
评论 (0) |
编辑

2008年10月9日
最近一直在使用 ASP.NET,由于之前大部分工作都是使用 WinForm,对 ASP.NET 的理解还只是停留在表面,所以借着这次机会,深入的研究一下 ASP.NET。原则是尽量使用 ASP.NET 的编程模型和 Web 控件实现业务交互。
GridView 是 ASP.NET 2.0 新增加的 Web 控件,拥有比 DataGrid 更多的扩展和改进。使用 GridView 可以很容易的实现数据分页,但是遗憾的是,在缺省情况下,当仅有一页数据时, GridView 不显示 Pager 分页行,这非常让人郁闷。

在网上搜索了一下解决此问题的有关方法,基本的思路都是使用自定义 Pager,自己实现分页显示。这个思路很好,可是我的应用并不复杂,对分页也没有特殊的要求,只是能显示就好,为了这么点要求重写写那么多代码,太不划算。有没有好的解决方法呢?
还真不是没办法,我发现 GridView 的 Controls 集合中包括了 Header、DataRow、Footer、Pager等等所有可以显示的行,而且不管有没有显示,这些行都包含在 Controls 集合中,只不过仅有一页数据时,Pager 行的 Visible 属性被设置为了 false。既然如此,只要在数据绑定结束后把 Pager 行的 Visible 重新设置为 true 不就解决问题了吗?下面是解决方法:
public static void gridView_DataBound(object sender, EventArgs e)
{
if (gridView.Rows.Count != 0)
{
Control table = gridView.Controls[0];
int count = table.Controls.Count;
table.Controls[count - 1].Visible = true;
}
}
posted @
2008-10-09 10:25 zsi 阅读(123) |
评论 (1) |
编辑

2008年9月3日
9月2日Google正式发布了其开源浏览器Chrome的Beta版下载。下载地址
作为开发人员,除了享受Google浏览器带给我们的新鲜感觉和全新体验外,不自觉的会思考其与其他浏览器到兼容性问题,毕竟因为这一点我们已经被IE6、IE7、FireFox搞得焦头烂额了。这还不算刚刚发布Beta2的IE8,现在又来了Chrome,我们不禁要问:Chrome,你行吗?
Google Chrome浏览器借鉴了一些源自Apple WebKit和 Mozilla Firefox的技术,从这一点上来说,Chrome浏览器与FF更接近。经过简单的试用,我们发现Chrome的兼容性很好,无论是Google、百度、新浪,还是豆瓣、鲜果都能够正常显示。而且特别值得一提的是,Chrome的页面加载速度很快,不知道是不是采用独立进程的设计结构有关。
尽管如此,Chrome对一些页面元素的呈现还是显示了独到之处。例如,ASP.NET的Menu对象,无论IE,还是FireFox都是以<table>的方式呈现,如:

Code
<table id="ctl00_navMenu" class="ctl00_navMenu_2" cellpadding="0" cellspacing="0" border="0">
<tr>
<td onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)" onkeyup="Menu_Key(this)" id="ctl00_navMenun0"><table cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td style="white-space:nowrap;"><a class="ctl00_navMenu_1" href="menu1.aspx">菜单项一</a></td>
</tr>
</table></td><td style="width:3px;"></td><td onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)" onkeyup="Menu_Key(this)" id="ctl00_navMenun1"><table cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td style="white-space:nowrap;"><a class="ctl00_navMenu_1" href="menu2.aspx">菜单项二</a></td>
</tr>
</table></td><td style="width:3px;"></td><td onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)" onkeyup="Menu_Key(this)" id="ctl00_navMenun2"><table class="selected ctl00_navMenu_4" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td style="white-space:nowrap;"><a class="ctl00_navMenu_1 selected ctl00_navMenu_3" href="menu3.aspx" style="border-style:none;font-size:1em;">菜单项三</a></td>
</tr>
</table></td>
</tr>
</table>
但是Chrome则不同,Chrome使用了另外一种呈现方式,这应该是Chrome做得特殊处理,如下:

Code
<div id="ctl00_navMenu">
<span><a class="ctl00_navMenu_1" href="menu1.aspx">菜单项一</a></span>
<span><a class="ctl00_navMenu_1" href="menu2.aspx">菜单项二</a></span>
<span><a class="ctl00_navMenu_1" href="menu3.aspx">菜单项三</a></span>
</div>
可以发现Chrome用<div>替换了外层的<table>,使用<span>替换了嵌套的<table>,经过处理后,呈现的代码被大大精简,而且更符合当前div+css的Web设计潮流。
无论如何,Google Chrome更我们带来了完全不同于以往的全新体验,而且目前仅是Beta版本,相信随着Google团队的不断改进,Google Chrome浏览器能够带给我们更多的惊喜。
Update:
看到朋友们的回复中提到了Apple的Safari,急忙从Apple网站上下载了最新的Windows版,测试相同的代码,发现Safari的呈现代码和Chrome一样,是不是因为Chrome使用了Apple WebKit的原因?
另在ASP.NET论坛有人回复说:
Safari and IE5.0 are considered downlevel browsers by ASP.NET. By default you won't get rich renderings for either of those.
ASP.NET将Safari和IE5.0看作低级浏览器,默认情况下使用这两种浏览器不能得到内容丰富的呈现。
如果这和Chrome使用了Apple WebKit有关,就好解释了。Chrome浏览器不同于IE、FF的呈现与ASP.NET有关,ASP.NET将Chrome认为是低级浏览器,返回了简单代码,并非浏览器自身做了特殊处理。
Update2:
何为downlevel browsers?下层浏览器
具有基本特性和功能的早期浏览器。不支持脚本编辑、动态 HTML (DHTML)、DHTML 行为或可扩展标记语言 (XML) 的浏览器通常被视为下层浏览器。
posted @
2008-09-03 12:08 zsi 阅读(1984) |
评论 (26) |
编辑

2008年1月26日
最近使用UnRARNet 处理 RAR格式的压缩文件。UnRARNet 是由
RARLab 随 unrar.dll 控件一起提供的.net 平台的封装。UnRARNet 使用VB.net语言,应该说对unrar.dll 进行了近乎完美的封装,几乎所有压缩和解压缩工作都完成的很漂亮。
不过,最近在测试解压缩文件时,遇到一个 System.Runtime.InteropServices.
SEHException 异常,异常信息是“外部组件发生异常”。具体位置是在
Decompressor 类的 Load
FileList() 方法中,其中有一句
mRARHandle = RAROpenArchiveEx(uRAREx)
是调用 unrar.dll 外部组件的
RAROpenArchiveEx() 方法,异常就发生在这里。
微软关于SEHExcption的描述中说:
SEHException 类处理从非托管代码引发的、但尚未映射到另一个 .NET Framework 异常的 SEH 错误。
SEHException 类还响应
HRESULT E_FAIL(它具有值
0x80004005)。
.NET Framework 经常会遇到非托管 SEH 异常,这些异常自动映射到托管等效项。例如,STATUS_NO_MEMORY SEH 异常自动映射到 OutOfMemoryException 类,而 STATUS_ACCESS_VIOLATION SEH 异常自动映射到 NullReferenceException 类。但是默认情况下,任何未自动映射到特定异常的 SEH 异常将映射到 SEHException 类。
我用Google搜索网页和Google Groups,都没有发现解决这类问题的方法,看来我足够幸运:),让我先碰到了。
经过仔细分析,发现问题出在压缩文件的注释上,当注释长度超过一个临界值时,就会发生 SEHException 外部组件异常。RAR 命令指南中提到RAR 压缩包的最大注释长度是 62000 字节,而测试的压缩文件注释只有19000多个字节,完全没有超出最大注释长度。因为注释长度而发生异常似乎没有道理。难道是UnRARNet有问题?
再回过头看 Decompressor 类,发现在 Init() 方法中有这么一段代码:
uRAREx.CmtBuf = Space(16384)
uRAREx.CmtBufSize = 16384
uRAREx.ArcName = mRARFile
uHeaderEx.CmtBuf = Space(16384)
原来,UnRARNet 将默认的注释长度设置成了 16384,难怪解压缩时发生异常了。将注释长度设置成RAR 压缩包的最大注释长度62000,测试通过:)
posted @
2008-01-26 11:48 zsi 阅读(290) |
评论 (0) |
编辑

2007年6月14日
服务器出了些小毛病,总是报告“无法打开到 SQL Server 的连接”,如下
在建立与服务器的连接时出错。在连接到 SQL Server 2005 时,在默认的设置下 SQL Server 不允许进行远程连接可能会导致此失败。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接) 
找了一些资料,说什么的都有,有说是因为装了SQL Server 2005的原因,有的说是.NET 2.0的名为LocalSqlServer的内置字符串的原因……但是我的数据库使用的是SQL Server 2000,操作系统是Windows 2003。没有使用到SQL Server 2005,也没有安装过SQL Server 2005,因此,可以排除这些因素。
连接字符串配置都是正确的,之前测试也没有任何问题。server使用的是IP地址,能够Ping通,也不会是计算机名称无法解析的原因。
但是,使用telnet [IP地址] 1433检查时发现,无法连接。根据一些资料的说法,可能和没有安装SQL Server 2000的补丁程序有关。如果版本号低于2039,就有可能会产生上述问题。使用 select @@version 命令查看SQL Server版本发现版本号是194,的确没有安装SP4。
死马且当活马医,抓住一根救命稻草,即使不是这个原因,也要试一试。装上SP4后一试,果然可以正常连接了。不过为什么呢?谁知道?
posted @
2007-06-14 15:30 zsi 阅读(911) |
评论 (0) |
编辑

2005年5月10日
这两天在写一个小程序,帮助自己做一些碎且杂的工作。程序也没什么复杂的处理,应该很简单就完成了,谁知道却牵出一档子事儿来。到底怎么回事?请听我一一道来。
写过IO处理程序的人都知道,在VB.NET中,如果只指定了文件名,而没有指定目录,那么当读写文件时,程序从启动目录读取文件。也就是说:.NET默认以程序的启动目录为缺省目录。例如,我的程序放在C:\Test\bin\目录下,程序中有下面一段写文件的代码,方式I:
Dim sw As New StreamWriter(“abc.txt”)
sw.WriteLine(“ABCDEFG”)
sw.Close()
在程序运行中,StreamWriter将在C:\Test\bin\目录下创建一个名为abc.txt的文本文件。上面的代码与下面的代码是一样的,方式II:
' 用Application.StartupPath指定目录
Dim sw As New StreamWriter(Application.StartupPath & “\abc.txt”)
正因为如此,所以在我的小程序里,就是使用方式I。但是问题恰恰出在这里。后来,程序增加了一段代码,其中使用到了OpenFileDialog。就在增加这段代码以后,发现方式I中写abc.txt的代码失效了。每次我使用OpenFileDialog以后,再调用方式I的方法时,总是不能把内容写入C:\Test\bin\目录下的abc.txt文件中。
经过好多次测试,这个问题依然没有解决,我甚至怀疑这是否是.NET的Bug。前面的测试我都把重点放在了:.NET以程序的启动目录为默认目录。那段代码中。最后一次测试,我转移了目标,我想会不会是写文件的代码有问题呢?带着这个疑问,我把写文件的代码由方式I变成了方式II。测试,通过!
回过头来再看写文件的这段代码,方式II和方式I的差别在于是否明确指定了目录。如前面所言,.NET默认以程序的启动目录为缺省目录。但是在使用OpenFileDialog的情况下,缺省目录随OpenFileDialog打开的文件目录而变化。缺省目录变成了OpenFileDialog打开的文件所在的目录。如果打开了D:\My Documents\里面的文件,那么缺省目录就成了D:\My Documents\。当调用方式I的代码时,实际是在D:\My Documents\下创建并改写abc.txt文件,C:\Test\bin\abc.txt当然不会有变化。
总结:在程序中读写文件时应明确指定文件目录,尽量不使用.NET的缺省目录。这在大型系统中尤为重要,因为大系统中往往用到OpenFileDialog。
另外,还应该注意SaveFileDialog和FolderBrowserDialog。
posted @
2005-05-10 14:13 zsi 阅读(2264) |
评论 (9) |
编辑

2005年4月26日
在Visual Studio .net中创建ASP.NET程序,默认位置为
http://localhost/[WebApplicationName],新建立的ASP.NET程序在C盘的C:\Inetpub\wwwroot\建立与程序名称相同的文件夹。新文件的增加和修改也是在这个文件夹中完成的。但是,我不想让ASP.NET程序保存在C盘,原因有二:一,一般C盘是系统盘,我想尽量保持系统盘的干净,不在系统盘创建和删除文件,以免产生系统碎片;二,我的其他程序,例如WinForm程序,都存储在D盘或E盘的某个位置统一管理,我不想让ASP.NET程序例外。怎么办?答案当然是把ASP.NET程序剪切到其他位置保存。
1. 把ASP.NET程序剪切到新的位置
2. 打开IIS,新建一个虚拟目录,并将路径指定到ASP.NET程序的新位置。
3. 打开ASP.NET程序所在的目录,并打开[WebApplicationName].[vbproj].webinfo或[WebApplicationName].[csproj].webinfo文件文件,修改Web节点的URLPath属性为
http://localhost/[虚拟目录名称]/ [WebApplicationName].vbproj或
http://localhost/[虚拟目录名称]/ [WebApplicationName].csproj。
OK!大功告成。打开VS.NET试试一切正常。
posted @
2005-04-26 09:47 zsi 阅读(832) |
评论 (3) |
编辑

2005年4月20日
.NET的对象序列化真是好东西,以后要多多利用。
在使用.NET的序列化时,碰到过一些问题,还好,有丰富的MSDN可查,没有什么过不去的槛。在这里,把使用.NET序列化的经验小结一下。
1. 基本确认XmlSerializer使用UTF8对序列化的XML文档编码。
2. XmlSerializer只序列化声明为public的字段,属性,或带返回值的方法。
3. 如果要序列化属性,那么该属性必须是可读写的,即必须包含get和set,而不能是readonly或writeonly。
4. XmlAttribute,XmlAnyAttribute不能与XmlElement,XmlText,XmlAnyElement,XmlArray,XmlArrayItem一起使用。
5. XmlRoot只能用于一个类,XmlType可用于所有类。
6. 不同的类的XmlType不能相同,除非使用NameSpaces区分。
相关链接:
●
在.NET中实现对象序列化
●
对象序列化:使用System.Xml.Serialization命名空间
●
对象序列化:使用XmlSerializer走完最后一步
posted @
2005-04-20 15:19 zsi 阅读(973) |
评论 (0) |
编辑