﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-苍穹之铁十字-随笔分类-C#</title><link>http://www.blogjava.net/kuxiaoku/category/21188.html</link><description>收藏</description><language>zh-cn</language><lastBuildDate>Mon, 02 Apr 2007 00:08:39 GMT</lastBuildDate><pubDate>Mon, 02 Apr 2007 00:08:39 GMT</pubDate><ttl>60</ttl><item><title>DataGrid的数据过滤示例</title><link>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107845.html</link><dc:creator>苦笑枯</dc:creator><author>苦笑枯</author><pubDate>Thu, 18 Jan 2007 16:16:00 GMT</pubDate><guid>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107845.html</guid><wfw:comment>http://www.blogjava.net/kuxiaoku/comments/107845.html</wfw:comment><comments>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107845.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kuxiaoku/comments/commentRss/107845.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kuxiaoku/services/trackbacks/107845.html</trackback:ping><description><![CDATA[<p>这个示例演示了怎么样在DataGrid中筛选数据</p>
<p>/*DataDridFilterForm.aspx</p>
<p>前台程序</p>
<p>*/</p>
<p>&lt;%@ Page language="c#" Codebehind="DataGridFilterForm.aspx.cs"
AutoEventWireup="false"
Inherits="DataDridFilterDemo.DataDridFilterForm" %&gt;<br>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" &gt;<br>&lt;HTML&gt;<br>&nbsp;&lt;HEAD&gt;<br>&nbsp;&nbsp;&lt;title&gt;WebForm1&lt;/title&gt;<br>&nbsp;&nbsp;&lt;meta name="vs_snapToGrid" content="True"&gt;<br>&nbsp;&nbsp;&lt;meta name="vs_showGrid" content="True"&gt;<br>&nbsp;&nbsp;&lt;meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1"&gt;<br>&nbsp;&nbsp;&lt;meta name="CODE_LANGUAGE" Content="C#"&gt;<br>&nbsp;&nbsp;&lt;meta name="vs_defaultClientScript" content="JavaScript"&gt;<br>&nbsp;&nbsp;&lt;meta name="vs_targetSchema" content="<a href="http://schemas.microsoft.com/intellisense/ie5">http://schemas.microsoft.com/intellisense/ie5</a>"&gt;<br>&nbsp;&lt;/HEAD&gt;<br>&nbsp;&lt;body MS_POSITIONING="GridLayout"&gt;<br>&nbsp;&nbsp;&lt;form id="Form1" method="post" runat="server"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;FONT face="宋体"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:DropDownList id="ddlCategory" style="Z-INDEX: 101; LEFT: 120px; POSITION: absolute; TOP: 16px"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;runat="server" Width="106px" Height="26px" AutoPostBack="True"&gt;&lt;/asp:DropDownList&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:Label id="lblCategory" style="Z-INDEX: 102; LEFT: 32px; POSITION: absolute; TOP: 24px"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;runat="server"&gt;Category:&lt;/asp:Label&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:Label
id="lblPrice" style="Z-INDEX: 103; LEFT: 256px; POSITION: absolute;
TOP: 24px" runat="server"&gt;Price Range:&lt;/asp:Label&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:DropDownList id="ddlPrice" style="Z-INDEX: 104; LEFT: 368px; POSITION: absolute; TOP: 16px" runat="server"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AutoPostBack="True"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:ListItem Value="0" Selected="True"&gt;Any Price&lt;/asp:ListItem&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:ListItem Value="1"&gt;Cheap&lt;/asp:ListItem&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:ListItem Value="2"&gt;Moderate&lt;/asp:ListItem&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:ListItem Value="3"&gt;Expensive&lt;/asp:ListItem&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:ListItem Value="4"&gt;Absurdly Expensive&lt;/asp:ListItem&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/asp:DropDownList&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:DataGrid id="dgProduct" style="Z-INDEX: 105; LEFT: 224px; POSITION: absolute; TOP: 96px"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;runat="server"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;AlternatingItemStyle BackColor="#E8E6E6"&gt;&lt;/AlternatingItemStyle&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ItemStyle BackColor="#F1F1F1"&gt;&lt;/ItemStyle&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;HeaderStyle BackColor="#C0C0FF"&gt;&lt;/HeaderStyle&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/asp:DataGrid&gt;&lt;/FONT&gt;<br>&nbsp;&nbsp;&lt;/form&gt;<br>&nbsp;&lt;/body&gt;<br>&lt;/HTML&gt;<br></p>
<p>/*DataDridFilterForm.aspx.cs</p>
<p>后台处理程序</p>
<p>*/</p>
<p>using System;<br>using System.Collections;<br>using System.ComponentModel;<br>using System.Data;<br>using System.Data.SqlClient;<br>using System.Drawing;<br>using System.Web;<br>using System.Web.SessionState;<br>using System.Web.UI;<br>using System.Web.UI.WebControls;<br>using System.Web.UI.HtmlControls;</p>
<p>namespace DataDridFilterDemo<br>{<br>&nbsp;/// &lt;summary&gt;<br>&nbsp;/// WebForm1 的摘要说明。<br>&nbsp;/// &lt;/summary&gt;<br>&nbsp;public class DataDridFilterForm : System.Web.UI.Page<br>&nbsp;{<br>&nbsp;&nbsp;protected System.Web.UI.WebControls.DropDownList ddlCategory;<br>&nbsp;&nbsp;protected System.Web.UI.WebControls.Label lblCategory;<br>&nbsp;&nbsp;protected System.Web.UI.WebControls.Label lblPrice;<br>&nbsp;&nbsp;protected System.Web.UI.WebControls.DropDownList ddlPrice;<br>&nbsp;&nbsp;protected System.Web.UI.WebControls.DataGrid dgProduct;<br>&nbsp;&nbsp;public static string strCategory="CategoryID=1";<br>&nbsp;&nbsp;public static string strPrice="UnitPrice&gt;0";<br>&nbsp;<br>&nbsp;&nbsp;private void Page_Load(object sender, System.EventArgs e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;// 在此处放置用户代码以初始化页面<br>&nbsp;&nbsp;&nbsp;if(!IsPostBack)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;FillDropDownList();<br>&nbsp;&nbsp;&nbsp;&nbsp;DataFiller();<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;#region Web 窗体设计器生成的代码<br>&nbsp;&nbsp;override protected void OnInit(EventArgs e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;&nbsp;// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。<br>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;&nbsp;InitializeComponent();<br>&nbsp;&nbsp;&nbsp;base.OnInit(e);<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;/// &lt;summary&gt;<br>&nbsp;&nbsp;/// 设计器支持所需的方法 - 不要使用代码编辑器修改<br>&nbsp;&nbsp;/// 此方法的内容。<br>&nbsp;&nbsp;/// &lt;/summary&gt;<br>&nbsp;&nbsp;private void InitializeComponent()<br>&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;this.ddlCategory.SelectedIndexChanged += new System.EventHandler(this.FilterChange);<br>&nbsp;&nbsp;&nbsp;this.ddlPrice.SelectedIndexChanged += new System.EventHandler(this.FilterChange);<br>&nbsp;&nbsp;&nbsp;this.Load += new System.EventHandler(this.Page_Load);</p>
<p>&nbsp;&nbsp;}<br>&nbsp;&nbsp;#endregion</p>
<p>&nbsp;&nbsp;private void FillDropDownList()<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;string strCon="server=JOSEN;database=NorthWind;integrated security=true";<br>&nbsp;&nbsp;&nbsp;string strSqlCategory="select CategoryName,CategoryID from Categories";<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;SqlConnection objCon=new SqlConnection(strCon);<br>&nbsp;&nbsp;&nbsp;SqlDataAdapter objAdpt=new SqlDataAdapter(strSqlCategory,objCon);</p>
<p>&nbsp;&nbsp;&nbsp;DataSet ds=new DataSet();<br>&nbsp;&nbsp;&nbsp;objAdpt.Fill(ds);</p>
<p>&nbsp;&nbsp;&nbsp;ddlCategory.DataSource=ds;<br>&nbsp;&nbsp;&nbsp;ddlCategory.DataTextField="CategoryName";<br>&nbsp;&nbsp;&nbsp;ddlCategory.DataValueField="CategoryID";<br>&nbsp;&nbsp;&nbsp;ddlCategory.DataBind();<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;private void DataFiller()<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;string strCon="server=JOSEN;database=NorthWind;integrated security=true";<br>&nbsp;&nbsp;&nbsp;string strSqlProduct="select ProductID,ProductName,CategoryID,UnitPrice from Products";<br>&nbsp;&nbsp;&nbsp;SqlConnection objCon=new SqlConnection(strCon);<br>&nbsp;&nbsp;&nbsp;SqlDataAdapter objAdpt=new SqlDataAdapter(strSqlProduct,objCon);</p>
<p>&nbsp;&nbsp;&nbsp;DataSet objds=new DataSet();<br>&nbsp;&nbsp;&nbsp;objAdpt.Fill(objds,"dtProduct");</p>
<p>&nbsp;&nbsp;&nbsp;DataView dvUK=new DataView(objds.Tables["dtProduct"]);<br>&nbsp;&nbsp;&nbsp;dvUK.RowFilter=strCategory+" and "+strPrice;</p>
<p>&nbsp;&nbsp;&nbsp;this.dgProduct.DataSource=dvUK;<br>&nbsp;&nbsp;&nbsp;dgProduct.DataBind();<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;private void FilterChange(object sender, System.EventArgs e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;FilterByPrice(ddlPrice.SelectedItem.Text.ToString());<br>&nbsp;&nbsp;&nbsp;FilterByCategory(ddlCategory.SelectedItem.Value.ToString());//注意这里，用的是CategoryID而不是CategoryName<br>&nbsp;&nbsp;&nbsp;DataFiller();<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;private void FilterByPrice(string strChoice)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;switch(strChoice)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;case "Any Price":<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strPrice="UnitPrice&gt;0";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;&nbsp;case "Cheap":<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strPrice="UnitPrice&lt;20";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;&nbsp;case "Moderate":<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strPrice="UnitPrice&gt;19 and UnitPrice&lt;50";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;&nbsp;case "Expensive":<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strPrice="UnitPrice&gt;=50";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;&nbsp;case "Absurdly Expensive":<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strPrice="UnitPrice&gt;100";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}</p>
&nbsp;&nbsp;private void FilterByCategory(string strChoice)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;strCategory="CategoryID="+strChoice;<br>&nbsp;&nbsp;}<br>&nbsp;}<br>}<img src="http://www.blogjava.net/kuxiaoku/aggbug/94809.html" height="1" width="1"><br><br>
<div align="right"><a style="text-decoration: none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:16 <a href="http://www.blogjava.net/kuxiaoku/articles/94809.html#Feedback" target="_blank" style="text-decoration: none;">发表评论</a></div>
<br>文章来源:<a href="http://www.blogjava.net/kuxiaoku/articles/94809.html">http://www.blogjava.net/kuxiaoku/articles/94809.html</a> <img src ="http://www.blogjava.net/kuxiaoku/aggbug/107845.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:16 <a href="http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107845.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DataGrid控件分页显示的示例</title><link>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107846.html</link><dc:creator>苦笑枯</dc:creator><author>苦笑枯</author><pubDate>Thu, 18 Jan 2007 16:16:00 GMT</pubDate><guid>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107846.html</guid><wfw:comment>http://www.blogjava.net/kuxiaoku/comments/107846.html</wfw:comment><comments>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107846.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kuxiaoku/comments/commentRss/107846.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kuxiaoku/services/trackbacks/107846.html</trackback:ping><description><![CDATA[<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td class="artbody" valign="top">
            <p>/*</p>
            <p>实现DataGrid控件分页显示的示例</p>
            <p>*/</p>
            <p>前台处理程序</p>
            <p>//DataGridPageDemo.aspx</p>
            <p>&lt;%@ Page language="c#" Codebehind="DataGridPageDemo.aspx.cs"
            AutoEventWireup="false" Inherits="DataGridPageDemo.DataGridPageDemo"
            %&gt;<br>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" &gt;<br>&lt;HTML&gt;<br>&nbsp;&lt;HEAD&gt;<br>&nbsp;&nbsp;&lt;title&gt;WebForm1&lt;/title&gt;<br>&nbsp;&nbsp;&lt;meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1"&gt;<br>&nbsp;&nbsp;&lt;meta name="CODE_LANGUAGE" Content="C#"&gt;<br>&nbsp;&nbsp;&lt;meta name="vs_defaultClientScript" content="JavaScript"&gt;<br>&nbsp;&nbsp;&lt;meta name="vs_targetSchema" content="<a href="http://schemas.microsoft.com/intellisense/ie5">http://schemas.microsoft.com/intellisense/ie5</a>"&gt;<br>&nbsp;&lt;/HEAD&gt;<br>&nbsp;&lt;body MS_POSITIONING="GridLayout"&gt;<br>&nbsp;&nbsp;&lt;form id="Form1" method="post" runat="server"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;FONT face="宋体"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:DataGrid id="dgDemo" style="Z-INDEX: 101; LEFT: 8px; POSITION: absolute; TOP: 8px" runat="server"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Width="264px" Height="240px" AllowPaging="True"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;PagerStyle Mode="NumericPages"&gt;&lt;/PagerStyle&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/asp:DataGrid&gt;&lt;/FONT&gt;<br>&nbsp;&nbsp;&lt;/form&gt;<br>&nbsp;&lt;/body&gt;<br>&lt;/HTML&gt;<br></p>
            <p>&nbsp;</p>
            <p>//下面的是后台处理程序</p>
            <p>DataGridPageDemo.aspx.cs</p>
            <p>using System;<br>using System.Collections;<br>using System.ComponentModel;<br>using System.Data;<br>using System.Data.SqlClient;<br>using System.Drawing;<br>using System.Web;<br>using System.Web.SessionState;<br>using System.Web.UI;<br>using System.Web.UI.WebControls;<br>using System.Web.UI.HtmlControls;</p>
            <p>namespace DataGridPageDemo<br>{<br>&nbsp;/// &lt;summary&gt;<br>&nbsp;/// WebForm1 的摘要说明。<br>&nbsp;/// &lt;/summary&gt;<br>&nbsp;public class DataGridPageDemo : System.Web.UI.Page<br>&nbsp;{<br>&nbsp;&nbsp;protected System.Web.UI.WebControls.DataGrid dgDemo;<br>&nbsp;<br>&nbsp;&nbsp;private void Page_Load(object sender, System.EventArgs e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;// 在此处放置用户代码以初始化页面<br>&nbsp;&nbsp;&nbsp;if(!IsPostBack)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;DataFiller();<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}</p>
            <p>&nbsp;&nbsp;#region Web 窗体设计器生成的代码<br>&nbsp;&nbsp;override protected void OnInit(EventArgs e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;&nbsp;// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。<br>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;&nbsp;InitializeComponent();<br>&nbsp;&nbsp;&nbsp;base.OnInit(e);<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;/// &lt;summary&gt;<br>&nbsp;&nbsp;/// 设计器支持所需的方法 - 不要使用代码编辑器修改<br>&nbsp;&nbsp;/// 此方法的内容。<br>&nbsp;&nbsp;/// &lt;/summary&gt;<br>&nbsp;&nbsp;private void InitializeComponent()<br>&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;this.dgDemo.PageIndexChanged += new System.Web.UI.WebControls.DataGridPageChangedEventHandler(this.dgDemo_PageIndexChanged);<br>&nbsp;&nbsp;&nbsp;this.Load += new System.EventHandler(this.Page_Load);</p>
            <p>&nbsp;&nbsp;}<br>&nbsp;&nbsp;#endregion</p>
            <p>&nbsp;&nbsp;private void DataFiller()<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;string strConn="server=JOSEN;database=NorthWind;integrated security=true";<br>&nbsp;&nbsp;&nbsp;string strSql="select * from orders";<br>&nbsp;&nbsp;&nbsp;SqlConnection objCon=new SqlConnection(strConn);<br>&nbsp;&nbsp;&nbsp;SqlDataAdapter objAdapter=new SqlDataAdapter(strSql,objCon);<br>&nbsp;&nbsp;&nbsp;DataSet ds=new DataSet();<br>&nbsp;&nbsp;&nbsp;objAdapter.Fill(ds,"dtorder");</p>
            <p>&nbsp;&nbsp;&nbsp;dgDemo.DataSource=ds.Tables["dtorder"];<br>&nbsp;&nbsp;&nbsp;dgDemo.DataBind();</p>
            <p>&nbsp;&nbsp;}</p>
            <p>&nbsp;&nbsp;private void dgDemo_PageIndexChanged(object source, System.Web.UI.WebControls.DataGridPageChangedEventArgs e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;dgDemo.CurrentPageIndex=e.NewPageIndex;<br>&nbsp;&nbsp;&nbsp;DataFiller();<br>&nbsp;&nbsp;}<br>&nbsp;}<br>}<br></p>
            </td>
        </tr>
        <tr>
            <td valign="top">&nbsp;</td>
        </tr>
        <tr>
            <td class="artfooter" align="right" valign="top">
            <br>
            </td>
        </tr>
    </tbody>
</table>
<img src="http://www.blogjava.net/kuxiaoku/aggbug/94810.html" height="1" width="1"><br><br>
<div align="right"><a style="text-decoration: none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:16 <a href="http://www.blogjava.net/kuxiaoku/articles/94810.html#Feedback" target="_blank" style="text-decoration: none;">发表评论</a></div>
<br>文章来源:<a href="http://www.blogjava.net/kuxiaoku/articles/94810.html">http://www.blogjava.net/kuxiaoku/articles/94810.html</a> <img src ="http://www.blogjava.net/kuxiaoku/aggbug/107846.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:16 <a href="http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107846.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用DataGrid控件更新删除数据示例</title><link>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107847.html</link><dc:creator>苦笑枯</dc:creator><author>苦笑枯</author><pubDate>Thu, 18 Jan 2007 16:15:00 GMT</pubDate><guid>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107847.html</guid><wfw:comment>http://www.blogjava.net/kuxiaoku/comments/107847.html</wfw:comment><comments>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107847.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kuxiaoku/comments/commentRss/107847.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kuxiaoku/services/trackbacks/107847.html</trackback:ping><description><![CDATA[		<br>
<p>/*UpdateDelForm.aspx</p>
<p>前台程序代码</p>
<p>*/</p>
<p>&lt;%@ Page language="c#" Codebehind="UpdateDelForm.aspx.cs"
AutoEventWireup="false" Inherits="UpdateDelDbDemo.UpdateDelForm" %&gt;<br>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" &gt;<br>&lt;HTML&gt;<br>&nbsp;&lt;HEAD&gt;<br>&nbsp;&nbsp;&lt;title&gt;WebForm1&lt;/title&gt;<br>&nbsp;&nbsp;&lt;meta name="vs_snapToGrid" content="False"&gt;<br>&nbsp;&nbsp;&lt;meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1"&gt;<br>&nbsp;&nbsp;&lt;meta name="CODE_LANGUAGE" Content="C#"&gt;<br>&nbsp;&nbsp;&lt;meta name="vs_defaultClientScript" content="JavaScript"&gt;<br>&nbsp;&nbsp;&lt;meta name="vs_targetSchema" content="<a href="http://schemas.microsoft.com/intellisense/ie5">http://schemas.microsoft.com/intellisense/ie5</a>"&gt;<br>&nbsp;&lt;/HEAD&gt;<br>&nbsp;&lt;body MS_POSITIONING="GridLayout"&gt;<br>&nbsp;&nbsp;&lt;form id="Form1" method="post" runat="server"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;FONT face="宋体"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:DataGrid id="dgDemo" runat="server" AutoGenerateColumns="False" GridLines="Horizontal"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Columns&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:BoundColumn DataField="ID" ReadOnly="True" HeaderText="UserID"&gt;&lt;/asp:BoundColumn&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:BoundColumn DataField="FirstName" HeaderText="FirstName"&gt;&lt;/asp:BoundColumn&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:BoundColumn DataField="LastName" HeaderText="LastName"&gt;&lt;/asp:BoundColumn&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:BoundColumn DataField="address" HeaderText="Address"&gt;&lt;/asp:BoundColumn&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:EditCommandColumn
ButtonType="LinkButton" UpdateText="更新" CancelText="取消"
EditText="编辑"&gt;&lt;/asp:EditCommandColumn&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:ButtonColumn Text="删除" CommandName="Delete"&gt;&lt;/asp:ButtonColumn&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Columns&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/asp:DataGrid&gt;&lt;/FONT&gt;<br>&nbsp;&nbsp;&lt;/form&gt;<br>&nbsp;&lt;/body&gt;<br>&lt;/HTML&gt;</p>
<p>/*UpdateDelForm.aspx.cs</p>
<p>后台程序代码</p>
<p>*/</p>
<p>using System;<br>using System.Collections;<br>using System.ComponentModel;<br>using System.Data;<br>using System.Data.SqlClient;<br>using System.Drawing;<br>using System.Web;<br>using System.Web.SessionState;<br>using System.Web.UI;<br>using System.Web.UI.WebControls;<br>using System.Web.UI.HtmlControls;</p>
<p>namespace UpdateDelDbDemo<br>{<br>&nbsp;/// &lt;summary&gt;<br>&nbsp;/// WebForm1 的摘要说明。<br>&nbsp;/// &lt;/summary&gt;<br>&nbsp;public class UpdateDelForm : System.Web.UI.Page<br>&nbsp;{<br>&nbsp;&nbsp;protected System.Web.UI.WebControls.DataGrid dgDemo;<br>&nbsp;&nbsp;private string strCon="server=JOSEN;database=testDb;integrated security=true";<br>&nbsp;&nbsp;private string strSqlSelect="select * from UserInfo";<br>&nbsp;&nbsp;private SqlConnection objCon;<br>&nbsp;<br>&nbsp;&nbsp;private void Page_Load(object sender, System.EventArgs e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;// 在此处放置用户代码以初始化页面<br>&nbsp;&nbsp;&nbsp;if(!IsPostBack)<br>&nbsp;&nbsp;&nbsp;&nbsp;LoadGrid();<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;#region Web 窗体设计器生成的代码<br>&nbsp;&nbsp;override protected void OnInit(EventArgs e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;&nbsp;// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。<br>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;&nbsp;InitializeComponent();<br>&nbsp;&nbsp;&nbsp;base.OnInit(e);<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;/// &lt;summary&gt;<br>&nbsp;&nbsp;/// 设计器支持所需的方法 - 不要使用代码编辑器修改<br>&nbsp;&nbsp;/// 此方法的内容。<br>&nbsp;&nbsp;/// &lt;/summary&gt;<br>&nbsp;&nbsp;private void InitializeComponent()<br>&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;this.dgDemo.CancelCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.dgDemo_CancelCommand);<br>&nbsp;&nbsp;&nbsp;this.dgDemo.EditCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.dgDemo_EditCommand);<br>&nbsp;&nbsp;&nbsp;this.dgDemo.UpdateCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.dgDemo_UpdateCommand);<br>&nbsp;&nbsp;&nbsp;this.dgDemo.DeleteCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.dgDemo_DeleteCommand);<br>&nbsp;&nbsp;&nbsp;this.Load += new System.EventHandler(this.Page_Load);</p>
<p>&nbsp;&nbsp;}<br>&nbsp;&nbsp;#endregion<br>&nbsp;&nbsp;//读取数据并帮定到ＤａｔａＧｒｉｄ<br>&nbsp;&nbsp;private void LoadGrid()<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;Connect();<br>&nbsp;&nbsp;&nbsp;SqlDataAdapter objAdpt=new SqlDataAdapter(strSqlSelect,objCon);<br>&nbsp;&nbsp;&nbsp;DataSet ds=new DataSet();<br>&nbsp;&nbsp;&nbsp;objAdpt.Fill(ds,"dtUserInfo");</p>
<p>&nbsp;&nbsp;&nbsp;dgDemo.DataSource=ds;<br>&nbsp;&nbsp;&nbsp;dgDemo.DataBind();<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;//建立数据库的连接<br>&nbsp;&nbsp;private void Connect()<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;if(objCon==null)<br>&nbsp;&nbsp;&nbsp;&nbsp;objCon=new SqlConnection(strCon);<br>&nbsp;&nbsp;&nbsp;if(objCon.State==ConnectionState.Closed)<br>&nbsp;&nbsp;&nbsp;&nbsp;objCon.Open();<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;//断开数据库的连接<br>&nbsp;&nbsp;private void Disconnect()<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;objCon.Close();<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;private void dgDemo_EditCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;dgDemo.EditItemIndex=e.Item.ItemIndex;<br>&nbsp;&nbsp;&nbsp;LoadGrid();<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;private void dgDemo_CancelCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;dgDemo.EditItemIndex=-1;<br>&nbsp;&nbsp;&nbsp;LoadGrid();<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;private void dgDemo_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;string strUserID=e.Item.Cells[0].Text;<br>&nbsp;&nbsp;&nbsp;//string strUserID=((TextBox)e.Item.Cells[0].Controls[0]).Text;<br>&nbsp;&nbsp;&nbsp;string strFirstName=((TextBox)e.Item.Cells[1].Controls[0]).Text;<br>&nbsp;&nbsp;&nbsp;string strLastName=((TextBox)e.Item.Cells[2].Controls[0]).Text;<br>&nbsp;&nbsp;&nbsp;string strAddress=((TextBox)e.Item.Cells[3].Controls[0]).Text;</p>
<p>&nbsp;&nbsp;&nbsp;dgDemo.EditItemIndex=-1;<br>&nbsp;&nbsp;&nbsp;//此方法具体处理数据库的更新<br>&nbsp;&nbsp;&nbsp;UpdateRecord(strUserID,strFirstName,strLastName,strAddress);<br>&nbsp;&nbsp;&nbsp;//调用此方法从数据库读取数据<br>&nbsp;&nbsp;&nbsp;LoadGrid();</p>
<p>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;private void UpdateRecord(string strUserID, string strFirstName, string strLastName, string strAddress)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;Connect();<br>&nbsp;&nbsp;&nbsp;SqlDataAdapter objAdpt=new SqlDataAdapter(strSqlSelect,objCon);<br>&nbsp;&nbsp;&nbsp;DataSet ds=new DataSet();<br>&nbsp;&nbsp;&nbsp;objAdpt.Fill(ds,"dtUserInfo");<br>&nbsp;&nbsp;&nbsp;Disconnect();</p>
<p>&nbsp;&nbsp;&nbsp;DataTable tbl=ds.Tables["dtUserInfo"];<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;//设定表的主键<br>&nbsp;&nbsp;&nbsp;DataColumn[] myKey=new DataColumn[1];<br>&nbsp;&nbsp;&nbsp;myKey[0]=tbl.Columns["ID"];<br>&nbsp;&nbsp;&nbsp;tbl.PrimaryKey=myKey;<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;DataRow dr=tbl.Rows.Find(strUserID);<br>&nbsp;&nbsp;&nbsp;//dr["ID"]=strUserID;<br>&nbsp;&nbsp;&nbsp;dr["FirstName"]=strFirstName;<br>&nbsp;&nbsp;&nbsp;dr["LastName"]=strLastName;<br>&nbsp;&nbsp;&nbsp;dr["address"]=strAddress;</p>
<p>&nbsp;&nbsp;&nbsp;SqlCommandBuilder cb=new SqlCommandBuilder(objAdpt);<br>&nbsp;&nbsp;&nbsp;Connect();<br>&nbsp;&nbsp;&nbsp;objAdpt.Update(ds,"dtUserInfo");<br>&nbsp;&nbsp;&nbsp;Disconnect();<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;private void dgDemo_DeleteCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)<br>&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;string strUserID=e.Item.Cells[0].Text;</p>
<p>&nbsp;&nbsp;&nbsp;dgDemo.EditItemIndex=-1;<br>&nbsp;&nbsp;&nbsp;DelRecord(strUserID);<br>&nbsp;&nbsp;&nbsp;//调用此方法从数据库读取数据<br>&nbsp;&nbsp;&nbsp;LoadGrid();<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;private void DelRecord(string strUserID)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;Connect();<br>&nbsp;&nbsp;&nbsp;SqlDataAdapter objAdpt=new SqlDataAdapter(strSqlSelect,objCon);<br>&nbsp;&nbsp;&nbsp;DataSet ds=new DataSet();<br>&nbsp;&nbsp;&nbsp;objAdpt.Fill(ds,"dtUserInfo");<br>&nbsp;&nbsp;&nbsp;Disconnect();</p>
<p>&nbsp;&nbsp;&nbsp;DataTable tbl=ds.Tables["dtUserInfo"];<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;//设定表的主键<br>&nbsp;&nbsp;&nbsp;DataColumn[] myKey=new DataColumn[1];<br>&nbsp;&nbsp;&nbsp;myKey[0]=tbl.Columns["ID"];<br>&nbsp;&nbsp;&nbsp;tbl.PrimaryKey=myKey;<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;DataRow dr=tbl.Rows.Find(strUserID);<br>&nbsp;&nbsp;&nbsp;dr.Delete();</p>
&nbsp;&nbsp;&nbsp;SqlCommandBuilder cb=new SqlCommandBuilder(objAdpt);<br>&nbsp;&nbsp;&nbsp;Connect();<br>&nbsp;&nbsp;&nbsp;objAdpt.Update(ds,"dtUserInfo");<br>&nbsp;&nbsp;&nbsp;Disconnect();<br>&nbsp;&nbsp;}<br>&nbsp;}<br>}<br><img src="http://www.blogjava.net/kuxiaoku/aggbug/94807.html" height="1" width="1"><br><br>
<div align="right"><a style="text-decoration: none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:15 <a href="http://www.blogjava.net/kuxiaoku/articles/94807.html#Feedback" target="_blank" style="text-decoration: none;">发表评论</a></div>
<br>文章来源:<a href="http://www.blogjava.net/kuxiaoku/articles/94807.html">http://www.blogjava.net/kuxiaoku/articles/94807.html</a> <img src ="http://www.blogjava.net/kuxiaoku/aggbug/107847.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:15 <a href="http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107847.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>日历程序的使用示例</title><link>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107848.html</link><dc:creator>苦笑枯</dc:creator><author>苦笑枯</author><pubDate>Thu, 18 Jan 2007 16:15:00 GMT</pubDate><guid>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107848.html</guid><wfw:comment>http://www.blogjava.net/kuxiaoku/comments/107848.html</wfw:comment><comments>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107848.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kuxiaoku/comments/commentRss/107848.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kuxiaoku/services/trackbacks/107848.html</trackback:ping><description><![CDATA[<p>/*CalendarForm2.aspx</p>
<p>前台程序</p>
<p>*/</p>
<p>&lt;%@ Page language="c#" Codebehind="CalendarForm2.aspx.cs" AutoEventWireup="false" Inherits="CalendarDemo.CalendarForm2" %&gt;<br>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" &gt;<br>&lt;HTML&gt;<br>&nbsp;&lt;HEAD&gt;<br>&nbsp;&nbsp;&lt;title&gt;CalendarForm2&lt;/title&gt;<br>&nbsp;&nbsp;&lt;meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1"&gt;<br>&nbsp;&nbsp;&lt;meta name="CODE_LANGUAGE" Content="C#"&gt;<br>&nbsp;&nbsp;&lt;meta name="vs_defaultClientScript" content="JavaScript"&gt;<br>&nbsp;&nbsp;&lt;meta name="vs_targetSchema" content="<a href="http://schemas.microsoft.com/intellisense/ie5">http://schemas.microsoft.com/intellisense/ie5</a>"&gt;<br>&nbsp;&lt;/HEAD&gt;<br>&nbsp;&lt;body MS_POSITIONING="GridLayout"&gt;<br>&nbsp;&nbsp;&lt;form id="Form1" method="post" runat="server"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;FONT face="宋体"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:ListBox id="lbxEmployee" style="Z-INDEX: 101; LEFT: 224px; POSITION: absolute; TOP: 80px"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;runat="server" Width="144px" Height="264px" Rows="7" AutoPostBack="True"&gt;&lt;/asp:ListBox&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:Calendar id="calHire" style="Z-INDEX: 102; LEFT: 232px; POSITION: absolute; TOP: 384px" runat="server"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Width="312px" Height="160px"&gt;&lt;/asp:Calendar&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;asp:Label id="lblInfo" style="Z-INDEX: 103; LEFT: 232px; POSITION: absolute; TOP: 352px" runat="server"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Width="152px" Height="24px"&gt;display Dates&lt;/asp:Label&gt;&lt;/FONT&gt;<br>&nbsp;&nbsp;&lt;/form&gt;<br>&nbsp;&lt;/body&gt;<br>&lt;/HTML&gt;<br></p>
<p>/*CalendarForm2.aspx.cs</p>
<p>日历控件使用后台程序</p>
<p>*/</p>
<p>using System;<br>using System.Collections;<br>using System.ComponentModel;<br>using System.Data;<br>using System.Data.SqlClient;<br>using System.Drawing;<br>using System.Web;<br>using System.Web.SessionState;<br>using System.Web.UI;<br>using System.Web.UI.WebControls;<br>using System.Web.UI.HtmlControls;</p>
<p>namespace CalendarDemo<br>{<br>&nbsp;/// &lt;summary&gt;<br>&nbsp;/// CalendarForm2 的摘要说明。<br>&nbsp;/// &lt;/summary&gt;<br>&nbsp;public class CalendarForm2 : System.Web.UI.Page<br>&nbsp;{<br>&nbsp;&nbsp;protected System.Web.UI.WebControls.ListBox lbxEmployee;<br>&nbsp;&nbsp;protected System.Web.UI.WebControls.Calendar calHire;<br>&nbsp;&nbsp;protected System.Web.UI.WebControls.Label lblInfo;<br>&nbsp;<br>&nbsp;&nbsp;private void Page_Load(object sender, System.EventArgs e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;// 在此处放置用户代码以初始化页面<br>&nbsp;&nbsp;&nbsp;string strCon="server=JOSEN;database=NorthWind;integrated security=true";<br>&nbsp;&nbsp;&nbsp;string strSql="select EmployeeID,LastName,FirstName,HireDate from Employees";</p>
<p>&nbsp;&nbsp;&nbsp;SqlConnection objCon=new SqlConnection(strCon);<br>&nbsp;&nbsp;&nbsp;SqlDataAdapter objAdpt=new SqlDataAdapter(strSql,objCon);</p>
<p>&nbsp;&nbsp;&nbsp;DataSet ds=new DataSet();<br>&nbsp;&nbsp;&nbsp;objAdpt.Fill(ds,"dtEmployee");</p>
<p>&nbsp;&nbsp;&nbsp;if(!IsPostBack)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;this.lbxEmployee.DataSource=ds;<br>&nbsp;&nbsp;&nbsp;&nbsp;lbxEmployee.DataTextField="LastName";<br>&nbsp;&nbsp;&nbsp;&nbsp;lbxEmployee.DataBind();<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;DateTime datHireDate;<br>&nbsp;&nbsp;&nbsp;&nbsp;datHireDate=Convert.ToDateTime(ds.Tables["dtEmployee"].Rows[lbxEmployee.SelectedIndex]["HireDate"]);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;lblInfo.Text=ds.Tables["dtEmployee"].Rows[lbxEmployee.SelectedIndex]["LastName"].ToString();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;this.calHire.VisibleDate=datHireDate;<br>&nbsp;&nbsp;&nbsp;&nbsp;calHire.SelectedDate=datHireDate;<br>&nbsp;&nbsp;&nbsp;&nbsp;lblInfo.Text+="hired on "+datHireDate;<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;#region Web 窗体设计器生成的代码<br>&nbsp;&nbsp;override protected void OnInit(EventArgs e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;&nbsp;// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。<br>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;&nbsp;InitializeComponent();<br>&nbsp;&nbsp;&nbsp;base.OnInit(e);<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;/// &lt;summary&gt;<br>&nbsp;&nbsp;/// 设计器支持所需的方法 - 不要使用代码编辑器修改<br>&nbsp;&nbsp;/// 此方法的内容。<br>&nbsp;&nbsp;/// &lt;/summary&gt;<br>&nbsp;&nbsp;private void InitializeComponent()<br>&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;this.Load += new System.EventHandler(this.Page_Load);</p>
<p>&nbsp;&nbsp;}<br>&nbsp;&nbsp;#endregion<br>&nbsp;}<br>}<br></p>
&nbsp;
<br><img src="http://www.blogjava.net/kuxiaoku/aggbug/94808.html" height="1" width="1"><br><br>
<div align="right"><a style="text-decoration: none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:15 <a href="http://www.blogjava.net/kuxiaoku/articles/94808.html#Feedback" target="_blank" style="text-decoration: none;">发表评论</a></div>
<br>文章来源:<a href="http://www.blogjava.net/kuxiaoku/articles/94808.html">http://www.blogjava.net/kuxiaoku/articles/94808.html</a> <img src ="http://www.blogjava.net/kuxiaoku/aggbug/107848.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:15 <a href="http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107848.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个魔术矩阵的例子</title><link>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107849.html</link><dc:creator>苦笑枯</dc:creator><author>苦笑枯</author><pubDate>Thu, 18 Jan 2007 16:14:00 GMT</pubDate><guid>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107849.html</guid><wfw:comment>http://www.blogjava.net/kuxiaoku/comments/107849.html</wfw:comment><comments>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107849.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kuxiaoku/comments/commentRss/107849.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kuxiaoku/services/trackbacks/107849.html</trackback:ping><description><![CDATA[<p>魔术矩阵是一个n*n的矩阵，其中N必须为奇数，然后将1至n的平方的整数依照指定的规则放入矩阵，完成后矩阵的各行各列以及对角线的元素值总和均会相同。</p>
<p>放置规则，第一个整数1一律被放置在第一行的中间位置，第二个值得位置必须放置在第一个值得左上角，因此，由1的位置往左一格，再往上一格，此时超出数组的范围，因此回到同一列的最下方。</p>
<p>同样，3必须放在2的左上角，4放在3的左上角，此时超出数组范围回到同一行的最右边空格。同此规则，来到5的位置，当我们要填入6的时候，其位置
已被数字1占据，因此将其放置到5的下方，接下来的数字则依规则一一放置到合适的位置，当填到15的时候，其左方与上方均没有位置，因此下一个数直接放置
于15的下方，完成了填入16的值，接下来的数目，均可以依上述的规则填写完成。</p>
<p>下面看看这个魔术矩阵的示例代码：</p>
<p>/*此类是主窗口，接受输入的奇数</p>
<p>MagicSquare.cs</p>
<p>*/</p>
<p>using System;<br>using System.Drawing;<br>using System.Collections;<br>using System.ComponentModel;<br>using System.Windows.Forms;<br>using System.Data;</p>
<p>namespace MagicSquare<br>{<br>&nbsp;/// &lt;summary&gt;<br>&nbsp;/// Form1 的摘要说明。<br>&nbsp;/// &lt;/summary&gt;<br>&nbsp;public class MagicSquare : System.Windows.Forms.Form<br>&nbsp;{<br>&nbsp;&nbsp;/// &lt;summary&gt;<br>&nbsp;&nbsp;/// 必需的设计器变量。<br>&nbsp;&nbsp;/// &lt;/summary&gt;<br>&nbsp;&nbsp;private System.ComponentModel.Container components = null;<br>&nbsp;&nbsp;private System.Windows.Forms.Label lblNumber;<br>&nbsp;&nbsp;private System.Windows.Forms.TextBox txbNumber;<br>&nbsp;&nbsp;private System.Windows.Forms.Button btnOK;<br>&nbsp;&nbsp;public int number=0;<br>&nbsp;&nbsp;public MagicSquare()<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;&nbsp;// Windows 窗体设计器支持所必需的<br>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;&nbsp;InitializeComponent();</p>
<p>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;&nbsp;// TODO: 在 InitializeComponent 调用后添加任何构造函数代码<br>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;/// &lt;summary&gt;<br>&nbsp;&nbsp;/// 清理所有正在使用的资源。<br>&nbsp;&nbsp;/// &lt;/summary&gt;<br>&nbsp;&nbsp;protected override void Dispose( bool disposing )<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;if( disposing )<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;if (components != null) <br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;components.Dispose();<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;base.Dispose( disposing );<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;#region Windows 窗体设计器生成的代码<br>&nbsp;&nbsp;/// &lt;summary&gt;<br>&nbsp;&nbsp;/// 设计器支持所需的方法 - 不要使用代码编辑器修改<br>&nbsp;&nbsp;/// 此方法的内容。<br>&nbsp;&nbsp;/// &lt;/summary&gt;<br>&nbsp;&nbsp;private void InitializeComponent()<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;this.lblNumber = new System.Windows.Forms.Label();<br>&nbsp;&nbsp;&nbsp;this.txbNumber = new System.Windows.Forms.TextBox();<br>&nbsp;&nbsp;&nbsp;this.btnOK = new System.Windows.Forms.Button();<br>&nbsp;&nbsp;&nbsp;this.SuspendLayout();<br>&nbsp;&nbsp;&nbsp;// <br>&nbsp;&nbsp;&nbsp;// lblNumber<br>&nbsp;&nbsp;&nbsp;// <br>&nbsp;&nbsp;&nbsp;this.lblNumber.Location = new System.Drawing.Point(48, 32);<br>&nbsp;&nbsp;&nbsp;this.lblNumber.Name = "lblNumber";<br>&nbsp;&nbsp;&nbsp;this.lblNumber.TabIndex = 0;<br>&nbsp;&nbsp;&nbsp;this.lblNumber.Text = "请输入奇数：";<br>&nbsp;&nbsp;&nbsp;// <br>&nbsp;&nbsp;&nbsp;// txbNumber<br>&nbsp;&nbsp;&nbsp;// <br>&nbsp;&nbsp;&nbsp;this.txbNumber.Location = new System.Drawing.Point(192, 32);<br>&nbsp;&nbsp;&nbsp;this.txbNumber.Name = "txbNumber";<br>&nbsp;&nbsp;&nbsp;this.txbNumber.TabIndex = 1;<br>&nbsp;&nbsp;&nbsp;this.txbNumber.Text = "";<br>&nbsp;&nbsp;&nbsp;// <br>&nbsp;&nbsp;&nbsp;// btnOK<br>&nbsp;&nbsp;&nbsp;// <br>&nbsp;&nbsp;&nbsp;this.btnOK.Location = new System.Drawing.Point(144, 80);<br>&nbsp;&nbsp;&nbsp;this.btnOK.Name = "btnOK";<br>&nbsp;&nbsp;&nbsp;this.btnOK.TabIndex = 2;<br>&nbsp;&nbsp;&nbsp;this.btnOK.Text = "OK";<br>&nbsp;&nbsp;&nbsp;this.btnOK.Click += new System.EventHandler(this.btnOK_Click);<br>&nbsp;&nbsp;&nbsp;// <br>&nbsp;&nbsp;&nbsp;// MagicSquare<br>&nbsp;&nbsp;&nbsp;// <br>&nbsp;&nbsp;&nbsp;this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);<br>&nbsp;&nbsp;&nbsp;this.ClientSize = new System.Drawing.Size(432, 117);<br>&nbsp;&nbsp;&nbsp;this.Controls.Add(this.btnOK);<br>&nbsp;&nbsp;&nbsp;this.Controls.Add(this.txbNumber);<br>&nbsp;&nbsp;&nbsp;this.Controls.Add(this.lblNumber);<br>&nbsp;&nbsp;&nbsp;this.Name = "MagicSquare";<br>&nbsp;&nbsp;&nbsp;this.Text = "MagicSquare";<br>&nbsp;&nbsp;&nbsp;this.ResumeLayout(false);</p>
<p>&nbsp;&nbsp;}<br>&nbsp;&nbsp;#endregion</p>
<p>&nbsp;&nbsp;/// &lt;summary&gt;<br>&nbsp;&nbsp;/// 应用程序的主入口点。<br>&nbsp;&nbsp;/// &lt;/summary&gt;<br>&nbsp;&nbsp;[STAThread]<br>&nbsp;&nbsp;static void Main() <br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;Application.Run(new MagicSquare());<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;private void btnOK_Click(object sender, System.EventArgs e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;number=Convert.ToInt32(txbNumber.Text.Trim());<br>&nbsp;&nbsp;&nbsp;if(number%2==1)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;this.Hide();<br>&nbsp;&nbsp;&nbsp;&nbsp;ShowResult&nbsp; result=new ShowResult(number);<br>&nbsp;&nbsp;&nbsp;&nbsp;result.Show();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;MessageBox.Show("您输入的不是奇数，请重新输入奇数！","输入错误");<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>&nbsp;}<br>}<br></p>
<p>/*这个类用来处理魔术矩阵的生成，以及在窗体上显示出来</p>
<p>Show.cs</p>
<p>*/</p>
<p>using System;<br>using System.Drawing;<br>using System.Collections;<br>using System.ComponentModel;<br>using System.Windows.Forms;</p>
<p>namespace MagicSquare<br>{<br>&nbsp;/// &lt;summary&gt;<br>&nbsp;/// Show 的摘要说明。<br>&nbsp;/// &lt;/summary&gt;<br>&nbsp;public class ShowResult : System.Windows.Forms.Form<br>&nbsp;{<br>&nbsp;&nbsp;/// &lt;summary&gt;<br>&nbsp;&nbsp;/// 必需的设计器变量。<br>&nbsp;&nbsp;/// &lt;/summary&gt;<br>&nbsp;&nbsp;private System.ComponentModel.Container components = null;<br>&nbsp;&nbsp;private int n;<br>&nbsp;&nbsp;private int[,] mm;<br>&nbsp;&nbsp;public ShowResult ()<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;&nbsp;// Windows 窗体设计器支持所必需的<br>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;&nbsp;InitializeComponent();</p>
<p>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;&nbsp;// TODO: 在 InitializeComponent 调用后添加任何构造函数代码<br>&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;public ShowResult (int number)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;n=number;<br>&nbsp;&nbsp;&nbsp;mm=new int[n,n];<br>&nbsp;&nbsp;&nbsp;AssignValue(n);&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;/// &lt;summary&gt;<br>&nbsp;&nbsp;/// 清理所有正在使用的资源。<br>&nbsp;&nbsp;/// &lt;/summary&gt;<br>&nbsp;&nbsp;protected override void Dispose( bool disposing )<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;if( disposing )<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;if(components != null)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;components.Dispose();<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;base.Dispose( disposing );<br>&nbsp;&nbsp;&nbsp;Application.Exit();<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;#region Windows 窗体设计器生成的代码<br>&nbsp;&nbsp;/// &lt;summary&gt;<br>&nbsp;&nbsp;/// 设计器支持所需的方法 - 不要使用代码编辑器修改<br>&nbsp;&nbsp;/// 此方法的内容。<br>&nbsp;&nbsp;/// &lt;/summary&gt;<br>&nbsp;&nbsp;private void InitializeComponent()<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;this.components = new System.ComponentModel.Container();<br>&nbsp;&nbsp;&nbsp;this.Size = new System.Drawing.Size(300,300);<br>&nbsp;&nbsp;&nbsp;this.Text = "ShowResult";<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;#endregion</p>
<p>&nbsp;&nbsp;<br>&nbsp;&nbsp;public void AssignValue(int n)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;int assignValue=1;<br>&nbsp;&nbsp;&nbsp;int p=n-1;<br>&nbsp;&nbsp;&nbsp;int col=p/2;<br>&nbsp;&nbsp;&nbsp;int row=0;<br>&nbsp;&nbsp;&nbsp;//初始化数组<br>&nbsp;&nbsp;&nbsp;for(int i=0;i&lt;n;i++)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;for(int j=0;j&lt;n;j++)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mm[i,j]=0;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;mm[row,col]=assignValue;<br>&nbsp;&nbsp;&nbsp;do<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;assignValue++;<br>&nbsp;&nbsp;&nbsp;&nbsp;col--;<br>&nbsp;&nbsp;&nbsp;&nbsp;row--;<br>&nbsp;&nbsp;&nbsp;&nbsp;if(col&lt;0&amp;&amp;row&lt;0)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row+=2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col+=1;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(col&lt;0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col=p;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(row&lt;0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row=p;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;if(mm[row,col]!=0)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col+=1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row+=2;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;mm[row,col]=assignValue;<br>&nbsp;&nbsp;&nbsp;}while(assignValue&lt;n*n);<br>&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;protected override void OnPaint(PaintEventArgs e)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;base.OnPaint (e);<br>&nbsp;&nbsp;&nbsp;Graphics g=this.CreateGraphics();<br>&nbsp;&nbsp;&nbsp;for(int i=0;i&lt;n;i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;for(int j=0;j&lt;n;j++)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.DrawString(mm[i,j].ToString(),new Font(FontFamily.GenericSansSerif.ToString(),15f),Brushes.YellowGreen,j*40+20,i*40+20);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;g.Dispose();</p>
<p>&nbsp;&nbsp;}</p>
&nbsp;}<br>}<img src="http://www.blogjava.net/kuxiaoku/aggbug/94805.html" height="1" width="1"><br><br>
<div align="right"><a style="text-decoration: none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:14 <a href="http://www.blogjava.net/kuxiaoku/articles/94805.html#Feedback" target="_blank" style="text-decoration: none;">发表评论</a></div>
<br>文章来源:<a href="http://www.blogjava.net/kuxiaoku/articles/94805.html">http://www.blogjava.net/kuxiaoku/articles/94805.html</a> <img src ="http://www.blogjava.net/kuxiaoku/aggbug/107849.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:14 <a href="http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107849.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Beginner with C#(来源csdn  kamphkb 的 Blog )</title><link>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107850.html</link><dc:creator>苦笑枯</dc:creator><author>苦笑枯</author><pubDate>Thu, 18 Jan 2007 16:14:00 GMT</pubDate><guid>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107850.html</guid><wfw:comment>http://www.blogjava.net/kuxiaoku/comments/107850.html</wfw:comment><comments>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107850.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kuxiaoku/comments/commentRss/107850.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kuxiaoku/services/trackbacks/107850.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 绪论 <br>c# 是一种简练，时髦（？），面向对象（object oriented），类型可靠（type-safe）的 <br>编程语言。它（发音：C sharp）是从c/c++发展而来的（？俺觉得更象是java），和c/c++ <br>是一个语系。所以，很容易被c/c++的程序员接受。c#的目标是结合Visual Basic的高产和 <br>C++质朴的力量。 <br><br>c#将会是vs7的一分子。vs7还支持vb,vc和标记语言——VBScript和JScript。所有这些语言 <br>都会在Next Generation Windows Services (NWGS) platform 中得到支持（c#就需要一个 <br>NWGS SDK包，可以在m$的网站上下载）。有了这个东东（NWGS），c#就不需要自己的类库， <br>而使用vc或vb这样一些成熟的库。c#也确实没有自己的类库。 <br>废话完了。 <br><br>1。1 一个老土的例子（就不能换换吗？）*/ <br>/* idontlikeHelloworld.cs : such a out sample :( */ <br>1: using System; <br>2: class idontlikeHelloworld <br>3: { <br>4: static void Main() { <br>5: Console.WriteLine("i dont like Hello world"); <br>6: Console.ReadLine(); <br>7: } <br>8: } <br>/* 如果俺要出书的话，会考虑换个好点的例子。 ^&amp;^ <br><br>先说说怎样运行。首先，你需要windows2000！（是的，就是它，请各位不要随地丢果皮—— <br>整个香蕉丢给俺就可以了。）然后，需要NWGS SDK！（82.4mb，不算很大噢。嘿嘿，好在 <br>它没有自己的类库。）安装后，在你的程序所在的目录下键入： <br><br>csc idontlikeHelloworld.cs (加上一个回车键） <br><br>是不是有点复古的味道？这个操作会在和你的*.cs相同目录下产生一个 <br>idontlikeHelloworld.exe文件。双击它，距可以看见： <br><br>i dont like Hello world <br><br>回车就可以结束它，非常简单。不过，也可以这样：把它存成后缀为.c的文件更好 <br>（即：idontlikeHelloworld.c）。这样就可以用vc的IDE进行打字，编辑。vc的 <br>txt editor是最棒的噢（又要vc，NO!!!）。然后： <br><br>csc idontlikeHelloworld.c (加上一个回车键） <br><br>最终效果是完全一样的。好，现在分析语法：（c#在语法上完全没有新意 :-| ） <br><br>1: using System; <br><br>using 其实是c++的关键字，在c#中的含义也相仿（就是说俺还不敢100%肯定，抱歉）。using <br>用在另一个关键字namespace之后。还是先看看namespace。 <br>语法（syntax）：（from MSDN） <br><br>namespace [identifier] { namespace-body } <br><br>俺的理解： <br>identifier：在这里就是System（请记住：c#和c/c++一样，是区分大小写的！）。System <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 必须在使用它的范围内是唯一的。即，不能够有第二个System，但可以有system。 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 而&#8220;它的范围&#8221;，俺不想详细解说，只有在实践中才可能掌握。而且，初学者根本 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不必知道！俺也是近来才知道还有个namespace和using。 ：） <br><br>在{ namespace-body }中的是真正有用的东东，包括第五行的&#8220;Console.WriteLine&#8221;的声明和 <br>定义（后面还会提到）。System是由NWGS定义的，咱们只需用（using）它即可。至于System在 <br>什么文件里定义，咱就不用管了！交给编译器（就是刚才那个&#8220;csc.exe&#8221;）去寻找。这就代替 <br>了c/c++中的&#8220;＃i nclude&#8221;，可以说是近了一步，避免大量烦人的细节。如果你没学过c/c++， <br>就不用理会。namespace 在后面还会谈到。 <br><br>2: class idontlikeHelloworld <br><br>class：是c语系中另一个关键字&#8220;类&#8221;。表示一系列的特性（官方说法：属性）和行为方法，有 <br>了它你的程序就可以&#8220;另类&#8221;，创造与别不同的有你特色的东东噢！在这里，俺就定义了 <br>&#8220;idontlikeHelloworld&#8221;。注意：这也是c#强制的，对于每一个可执行的程序都必须有。你想干 <br>的事就可以记录在紧跟着你定义的class后面的一对花括号。注意：&#8220;{&#8221;和&#8220;}&#8221;一一对应的， <br>&#8220;(&#8221;和&#8220;)&#8221;同样。 <br><br>4: static void Main() { <br><br>Main()是本例子第一个动作（行为方法），干的第一件事。它是属于俺定义的idontlikeHelloworld <br>类的方法。并且是c#强制的，是程序的真正开始！在紧跟在它后面的&#8220;{}&#8221;中的语句顺序，就是程序 <br>的运行顺序！本例中只有一行（第六行干嘛用？你可以去掉再编译一次看看），输出一句话。 <br><br>5: Console.WriteLine("i dont like Hello world"); <br><br>非常奇怪，Console（再次提醒：注意大小写）不是俺定义的，从何而来？它其实是属于System <br>namespace 的一个class。WriteLine()是Console类中的一个方法，用来显示一句话（字符串）。 <br>这里只是用了这个方法的1/18！并且是最简单之一！其他的有机会再说。你也可以用 <br>&#8220;Console.WriteLine&#8221;在&#8220;NGWS SDK Documentaion&#8221;中搜索&#8220;Console.WriteLine&#8221;，记住复选 <br>&#8220;仅搜索标题&#8221;，它会列出19项。好啦，完了！其实，还有&#8220;.&#8221;没说呢！呵呵...lei si la!!!! <br>（续前） <br>&#8220;.&#8221;被称为分隔符（separator），用来连接名字，如上面的&#8220;Console.WriteLine&#8221;，就把类和它的 <br>方法连接。通过这种方式，咱们就可以使用现成方法集合。这里再回顾一下俺的例子，看看namespace和 <br>&#8220;.&#8221;是如何连用的，还有为什么要使用namespace这个关键字。把例子稍微改一下：*/ <br>/* idontlikeHelloworld.cs */ <br>1: //using System; <br>2: class idontlikeHelloworld <br>3: { <br>4: static void Main() { <br>5: System.Console.WriteLine("i dont like Hello world"); <br>6: System.Console.ReadLine(); <br>7: } <br>8: } <br><br>/* 看见了，当俺注销掉&#8220;using System;&#8221;后，在第五行和第六行加了&#8220;System&#8221;。程序的结果不会改 <br>变。但是，很明显的这样比较罗嗦，所以引入了&#8220;namespace&#8221;。其实，class应该可以完成同样的功能。 <br>不过，设计者可能不想让一个关键字涵盖太多的功能。记得在c向c++发展的时候，引入了&#8220;class&#8221;，而 <br>不是扩展&#8220;struct&#8221;关键字的功能；又比如&#8220;=&#8221;只用于赋值，&#8220;==&#8221;只用于判断相等。这是c/c++和c# <br>在语法上其中一个重要的特点。这样设计的好处很多。有机会再聊噢。 <br>如果你没学过c/c++，以下的内容可以跳过。c#与c/c++在语法上还是有区别的，比如： <br>1。c#根本没有&#8220;::&#8221;；&#8220;-&gt;&#8221;只在程序中很小的片断中。在c#中应采用&#8220;.&#8221;。 <br>2。c#无须先声明定义，再使用。与java相同。 <br>3。c#取消了用&#8220;＃i nclude&#8221;导入其他的程序文本文件，而采用象征性的句柄引入他人的代码。这样一来， <br>&nbsp;&nbsp; 就排除了编程语言间的障碍，方便地使用其它语言编写的库。如&#8220;Console&#8221;类可以是c#或者是其他任一种语言编写的。
<p>1。2 自动化的内存管理（Automatic memory management） <br>手动管理内存需要程序员自行分配和释放内存块。这要求程序员有清晰的头脑和对整个运行过程有十分的 <br>把握（好难！）。而c#把程序员从这难以承担的任务中解放出来。在多数的情况下，这种自动内存管理提 <br>高代码的质量和程序员的生产力。并且，不会对程序的意图和执行产生幅面的影响（？俺可不相信m$的鬼 <br>话）。不过，估计比java的回收站好一点吧。因为c#出道迟嘛（尽胡扯）。好了，来看看例子。*/ <br><br>using System; <br>public class Stack <br>{ <br>&nbsp; private Node first = null; <br>&nbsp; public bool Empty { <br>&nbsp;&nbsp;&nbsp; get { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (first == null); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br>&nbsp; } <br>&nbsp; public object Pop() { <br>&nbsp;&nbsp;&nbsp; if (first == null) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new Exception("Can't Pop from an empty Stack."); <br>&nbsp;&nbsp;&nbsp; else { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; object temp = first.Value; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; first = first.Next; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return temp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br>&nbsp; } <br>&nbsp; public void Push(object o) { <br>&nbsp;&nbsp;&nbsp; first = new Node(o, first); <br>&nbsp; } <br>&nbsp; class Node <br>&nbsp; { <br>&nbsp;&nbsp;&nbsp; public Node Next; <br>&nbsp;&nbsp;&nbsp; public object Value; <br>&nbsp;&nbsp;&nbsp; public Node(object value): this(value, null) {} <br>&nbsp;&nbsp;&nbsp; public Node(object value, Node next) { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Next = next; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Value = value; <br>&nbsp;&nbsp;&nbsp; } <br>&nbsp; } <br>} <br><br>class Test <br>{ <br>&nbsp; static void Main() { <br>&nbsp;&nbsp;&nbsp; Stack s = new Stack(); <br>&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; 10; i++) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.Push(i); <br>&nbsp;&nbsp;&nbsp; while (!s.Empty) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(s.Pop()); <br>&nbsp; } <br>} <br>/* <br>stack类实现了一系列Node的实例。大家可以看看stack类的Push方法。Node的实例就是在Push方法中创建的。 <br>就是&#8220;first = new Node(o, first);&#8221;。请记住这个&#8220;new&#8221;噢。它就是用来创建类实例的。相关的语法太 <br>多，遛到后面用一节详细讲。这里只是要了解自动内存管理（Automatic memory management）好处？！&#8220;new&#8221; <br>是负责初始化类实例。而在c/c++中释放这些实例要用另一个关键字&#8220;delete&#8221;。但是在什么时候用delete呢， <br>这通常是很费神的活，老手也会阴沟里翻船。何况是俺呢！但在c#中有不用了。例子里就没有用&#8220;delete&#8221;。 <br>当Node的实例不需要时，垃圾收集器（garbage collector）自动销毁它，不用俺操心喽。这点到和java挺 <br>像的（可能是抄的）。 <br><br>在一个test类里，俺用了一个循环，对stack类的实例的Push方法赋值十次。于是，Push创建了Node的十个实 <br>例（instance）。然后用Pop把它们显示出来。其顺序正好与创建的顺序相反。 <br>这个例子相当的好，是stack <br>的一个典型，也很好的表述了自动内存管理的机制。但也不好懂，好在这一节不是写给毫无基础的网友看的。 <br>俺自个都花了几分钟看明白，各位大虾更是没问题。 <br><br>其实，当显示完了&#8220;10&#8221;以后，就会有一个Node的实例符合被释放的条件，但垃圾收集器并不一定会这样做。 <br>也就是说，它的行为并不确定（这和java一样，俺猜）。有时候，这种行为会带来一些负面影响。起码是性 <br>能降低。自动内存管理本身也是有问题的。因为它很难管理一些特殊情况。有一些关于java的垃圾收集器的 <br>文章也有提到。m$也不会好得了多少。所以，m$有个不安全代码的术语（unsafe code），用来为高级用户服 <br>务。即，用户可以不采用垃圾收集器。但必须用&#8220;unsafe&#8221;关键字显式声明之。这样就避免了用户不经意以 <br>外使用不安全代码。下面是一个例子：*/ <br><br>using System; <br>class Test <br>{ <br>&nbsp; unsafe static void WriteLocations(byte[] arr) { <br>&nbsp;&nbsp;&nbsp; fixed (byte *p_arr = arr) { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte *p_elem = p_arr; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; arr.Length; i++) { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte value = *p_elem; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string addr = int.Format((int) p_elem, "X"); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("arr[{0}] at 0x{1} is {2}", i,&nbsp; addr, value); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p_elem++; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br>&nbsp;&nbsp;&nbsp; } <br>&nbsp; } <br>&nbsp; static void Main() { <br>&nbsp;&nbsp;&nbsp; byte[] arr = new byte[] {1, 2, 3, 4, 5}; <br>&nbsp;&nbsp;&nbsp; WriteLocations(arr); <br>&nbsp; } <br>} <br>/* <br>俺对这个例子不是很满意，也让俺有点迷惑，有机会再自己写一个。很简单，只是可以用指针了！万岁！ <br>其实，俺对这一节最没有把握了！有不少地方都不能自圆其说！所以，请各位大虾大力批评。*/<br></p>
<pre>1。3 类型 <br>c#支持两种基本的类型：一种是值（value types），一种是引用（reference types）。值包括简单类型 <br>（char、int、和float），枚举（enum）和结构（struct）。引用包括类（class），界面（interface）， <br>代表（delegate）和数组阵列（array）。值与引用不同之处在于：值直接存储它的数据内容；而引用存储对象 <br>的引用。是不是粉费解？！打个比方吧。你在某地买了套别墅（好棒噢）。却从未去过，只知道地址，怎 <br>么办？你可以坐出租车，司机看了地址就知道怎样走不用你操心。你手里的地址就好像对象的名字，你把 <br>它写在程序中，就好像把地址给了司机。司机就是你的编译器，它知道该去哪。你豪华的房子就好比那个 <br>NGWS SDK开发包（82mb噢，够豪华了！俺的m啊--就这样烧喽）。房子里有你想要的东东，比如你想写一句 <br>话（i dont like Hello world），就好像上面例子，要用到&#8220;WriteLine&#8221;。于是，你就给出&#8220;WriteLine&#8221; <br>的地址，比如：&#8220;Console.WriteLine&#8221;。明白？！俺可累了。zzz...&nbsp; （强打精神）不知道你想到没有， <br>值和引用的区别可以引出一个重要特性。值的变量和变量存储的数据是一一对应的，唯一性。而引用则不 <br>然。引用中不同的变量可以引用同一个对象的实例。当其中一个变量改变实例的值时，其他引用这个实例的 <br>变量也会受到影响（当然，变量本身并没有改变，即，地址没变）。瞧，变量只是说明存储对象的位置（地 <br>址），而不是对象本身。就好像你漂亮的房子被烧了，但你的地址并没有改变，但地址对应的房子就没了。 <br>也许是别人也有这个地址，他去烧了你的房子！好了，在给个例子：*/ <br><br>1: using System; <br>2: class CValue <br>3: { <br>4: public int Value = 0; <br>5: } <br>6: class Test <br>7: { <br>8: static void Main() { <br>9: int val1 = 0; <br>10: int val2 = val1; <br>11: val2 = 123; <br>12: CValue ref1 = new CValue(); <br>13: CValue ref2 = ref1; <br>14: ref2.Value = 123; <br>15: Console.WriteLine("Values: {0}, {1}", val1, val2); <br>16: Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value); <br>17: } <br>18: } <br><br>/* 下面是输出的结果： <br>Values: 0, 123 <br>Refs: 123, 123 <br><br>啊哈，应该粉清楚了吧。变量val1和变量val2互不影响,它们各自有自己的存储空间。而ref2复制 <br>了ref1，所以，它们引用了同一个对象的实例。当改变它们其中一个的时候，就会影响到另一个的 <br>值。 <br></pre>
<pre><span id="ArticleContent1_ArticleContent1_lblContent">1。5 数组类型（Array types） <br><br>数组可以是一维的，也可是多维的。数祖的成员可以是整齐的，也可以是变长（jagged）的。 <br><br>一维的数组是最普通，最简单的。这里值给出一个例子，就不多解释了。*/ <br>using System; <br>class Test <br>{ <br>&nbsp;static void Main() { <br>&nbsp; int[] arr = new int[5]; <br>&nbsp; for (int i = 0; i &lt; arr.Length; i++) <br>&nbsp;&nbsp; arr[i] = i * i; <br>&nbsp; for (int i = 0; i &lt; arr.Length; i++) <br>&nbsp;&nbsp; Console.WriteLine("arr[{0}] = {1}", i, arr[i]); <br>&nbsp;} <br>} <br><br>/* 结果如下： <br>arr[0] = 0 <br>arr[1] = 1 <br>arr[2] = 4 <br>arr[3] = 9 <br>arr[4] = 16 <br><br>我们还可以比较的看看多维，规则，变长的数组的定义和赋值：*/ <br>class Test <br>{ <br>&nbsp;static void Main() { <br>&nbsp; int[] a1 = new int[] {1, 2, 3};&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //一维 <br>&nbsp; int[,] a2 = new int[,] {{1, 2, 3}, {4, 5, 6}};&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //二维 <br>&nbsp; int[,,] a3 = new int[10, 20, 30];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //三维 <br>&nbsp; int[][] j2 = new int[3][];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //变长 <br>&nbsp; j2[0] = new int[] {1, 2, 3}; <br>&nbsp; j2[1] = new int[] {1, 2, 3, 4, 5, 6}; <br>&nbsp; j2[2] = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9}; <br>&nbsp;} <br>} <br>/* <br>上面的例子给出了各种样式的数组。变量a1、a2和a3是规则数组。j2则是变长的数组。 <br>规则数组很容易就可以计算出它们的长度。比如a3的长度是：10*20*30=6000。相反，变长 <br>数组就有点不同，它的每一个维度都必须单独定义。如j2的第一维度是3，第二个是6，第 <br>三个是9，所以总长度是：1*3+1*6+1*9=18。 <br><br>上面对数组的赋值是严谨的风格，在某种情况下，我们可以简化写法，但我总觉得这种简化 <br>应用限制太多，容易出错。在这里就不作介绍了。这里再给一个例子说明函数中的参数如何 <br>赋值*/ <br>class Test <br>{ <br>&nbsp;static void F(long[] arr) {} <br>&nbsp;static void Main() { <br>&nbsp; F(new longt[] {1, 2, 3}); <br>&nbsp;} <br>}<br></span></pre>
<pre><span><span id="ArticleContent1_ArticleContent1_lblContent">赶出一编！请指正！ <br>1。6 统一系统类型（Type system unification） <br>c#独创了一种类型——统一系统类型（为了这个累刑，我头疼死了。谁有更好的名字，请务必告诉 <br>我）。总之，所有的其他类型，包括值和引用，都可以被当作统一系统类型来对待。从概念上说， <br>所有的类型都从它派生。这样，其他的类型就可以使用统一系统类型的属性和方法。包括一些&#8220;简 <br>单&#8221;类型，如：int。还是给个例子吧：*/ <br>using System; <br>class Test <br>{ <br>&nbsp; static void Main() { <br>&nbsp;&nbsp;&nbsp; Console.WriteLine(3.ToString()); <br>&nbsp; } <br>} <br>/*&#8220;3.ToString()&#8221;调用了object的&#8220;ToString()&#8221;方法。相信学过c/c++的朋友都知道要输出一个 <br>数字有多麻烦，现在就省事了。再看一个：*/ <br>class Test <br>{ <br>&nbsp; static void Main() { <br>&nbsp;&nbsp;&nbsp; int i = 123; <br>&nbsp;&nbsp;&nbsp; object o = i;&nbsp;&nbsp;&nbsp; // boxing <br>&nbsp;&nbsp;&nbsp; int j = (int) o;&nbsp; // unboxing <br>&nbsp; } <br>} <br>/* 这个像帽子戏法的例子中，从&#8220;int&#8221;转换成&#8220;object&#8221;，又转换回来。这样一来，在值和引用 <br>之间就架起了一座桥梁。这样有什么用呢。即兴举一个常见的例子...就min把。在c/c++中：*/ <br>// c/c++ code <br><br>void min(int i, int j) <br>{ <br>&nbsp; return ((i &lt; j) ? i : j); <br>} <br><br>/* 如果比较的不是int，或者说可能是int，也可能是float、double呢？可以这样：*/ <br><br>template&lt;class T&gt; <br>T min (T i, T j) <br>{ <br>&nbsp; return ((i &lt; j) ? i : j) <br>} <br><br>/* 用c#可以：*/ <br>void swap (object a, object b) <br>{ <br>&nbsp; return ((i &lt; j) ? i : j); <br>} <br><br>/* 我想大家一定看出来第二个例子要比较一个int和一个float的话，还需要一些转换，而第三个 <br>例子就可以比较所有的变量！这个灵活度简直太大了。所以，我私以为，大家使用时一定要小心！ <br>它在比较一个int和一个class的时候决不会报错的。呵呵，我发现我的翻译总是越跑越远，总是 <br>扣不住原文。篡改甚多，敬请原谅！</span></span></pre>
<pre><span></span>&nbsp;</pre>
<pre><span><span id="ArticleContent1_ArticleContent1_lblContent">1。7 语句（Statements） <br><br>c#借用了c/c++大多数的语句方法，不过仍然有些值得注意的地方。还有些地方是有所改动的。 <br>在这里，我只提一些c#特有的东东。 <br><br>1。7。10 &#8220;foreach&#8221;语句 <br>&#8220;foreach&#8221;语句列举一个集合内的所有元素，并对这些元素执行一系列的操作。还是看看例子吧：*/ <br><br>using System; <br>using System.Collections; <br>class Test <br>{ <br>&nbsp; static void WriteList(ArrayList list) { <br>&nbsp;&nbsp;&nbsp; foreach (object o in list) <br>&nbsp;&nbsp;&nbsp; { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i = (int) o;//如果是for语句，这里一定会报错！ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(0); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(++i); <br>&nbsp;&nbsp;&nbsp; } <br>&nbsp; } <br>&nbsp; static void Main() { <br>&nbsp;&nbsp;&nbsp; ArrayList list = new ArrayList(); <br>&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; 10; i++) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list.Add(i); <br>&nbsp;&nbsp;&nbsp; WriteList(list); <br>&nbsp; } <br>} <br>/*这个例子用&#8220;foreach&#8221;扫描了整个&#8220;list&#8221;，并把&#8220;list&#8221;中所有的元素打印出来。有时候还是 <br>挺方便的。 <br><br>1。7。15 安全检查开关（The checked and unchecked statements） <br>&#8220;checked&#8221;和&#8220;unchecked&#8221;语句用来控制数学运算和完整类型转换的检查工作。&#8220;checked&#8221;检查它 <br>作用的域中可能出现的违例，并抛出一个异常；而&#8220;unchecked&#8221;则阻止所有的检查。举个例子：*/ <br><br>using System; <br>class Test <br>{ <br>&nbsp;&nbsp; static int x = 1000000; <br>&nbsp;&nbsp; static int y = 1000000; <br>&nbsp;&nbsp; static int F() { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checked {return (x * y);}&nbsp;&nbsp;&nbsp;&nbsp; // 抛出 OverflowException <br>&nbsp;&nbsp; } <br>&nbsp;&nbsp; static int G() { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unchecked {return (x * y);}&nbsp;&nbsp; // 返回 -727379968 <br>&nbsp;&nbsp; } <br>&nbsp;&nbsp; static int H() { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return x * y;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 缺省状态。 <br>&nbsp;&nbsp; } <br>&nbsp;&nbsp; static void Main() { <br>&nbsp;&nbsp;&nbsp;&nbsp; F();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //可以注销掉此行试试。 <br>&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(G()); <br>&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(H()); <br>&nbsp;&nbsp; } <br>} <br><br>/* <br>在编译过程中不会有任何错误出现。因为&#8220;checked&#8221;和&#8220;unchecked&#8221;只在运行时才起作用。值得一说的是 <br>H()。它的缺省状态和编译器当前的缺省溢出检查的状态有关。但返回的结果肯定和F()或G()中的任一个相同。 <br>再看一个例子：*/ <br><br>using System; <br>class Test <br>{ <br>&nbsp;&nbsp; const int x = 1000000; <br>&nbsp;&nbsp; const int y = 1000000; <br>&nbsp;&nbsp; static int F() { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checked {return (x * y);}&nbsp;&nbsp;&nbsp; // 编译器警告（Compile warning）：溢出（overflow） <br>&nbsp;&nbsp; } <br>&nbsp;&nbsp; static int G() { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unchecked {return (x * y);}&nbsp; // 返回 -727379968 <br>&nbsp;&nbsp; } <br>&nbsp;&nbsp; static int H() { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return x * y;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 编译器警告（Compile warning）：溢出（overflow） <br>&nbsp;&nbsp; } <br>&nbsp;&nbsp; static void Main() { <br>&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(F());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //可以注销掉此行试试。 <br>&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(G()); <br>&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(H());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //可以注销掉此行试试。 <br>&nbsp;&nbsp; } <br>} <br><br>/* 当F()和H()求值的时候，就会引起一个编译警告。而在G()中，因为有了&#8220;unchecked&#8221;，屏蔽了这个警 <br>告。要注意的是&#8220;checked&#8221;和&#8220;unchecked&#8221;都不能对函数的返回值进行操作！比如：*/ <br>class Test <br>{ <br>&nbsp;&nbsp; static int Multiply(int x, int y) { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return x * y; <br>&nbsp;&nbsp; } <br>&nbsp;&nbsp; static int F() { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checked{ return Multiply(1000000, 1000000); } // 与 return Multiply(1000000, 1000000); <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 有相同的效果。 <br>} <br>/* 其实大家稍微想一下知道为什么m$没有这么做！对这个内容的讨论超出本文的范围和俺的能力之外哦。 <br><br>在c#中，所有的十六进制数都是uint。如果用强制类型转换会引起编译器报错。用&#8220;unchecked&#8221;则可以 <br>跳过这个机制，把uint的十六进制数转化为int。如：*/ <br><br>class Test <br>{ <br>&nbsp;&nbsp; public const int AllBits = unchecked((int)0xFFFFFFFF); <br>&nbsp;&nbsp; public const int HighBit = unchecked((int)0x80000000); <br>} <br><br>/* 上例所有的常数都是uint，而且超过了int的范围，没有&#8220;unchecked&#8221;，这种转换会引发一个编译器错 <br>误。注意：上面用的是&#8220;unchecked&#8221;操作符。不是语句。不过它们之间除了一个用&#8220;()&#8221;，另一个用 <br>&#8220;{}&#8221;以外，几乎一样。BTW，&#8220;checked&#8221;同样。 <br><br>1。7。16 &#8220;lock&#8221;语句（The lock statement） <br>&#8220;lock&#8221;获得一个相互排斥的对象锁定。（俺查过一些资料，但都没有清晰说明，暂不介绍）</span></span></pre>
<img src="http://www.blogjava.net/kuxiaoku/aggbug/94806.html" height="1" width="1"><br><br>
<div align="right"><a style="text-decoration: none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:14 <a href="http://www.blogjava.net/kuxiaoku/articles/94806.html#Feedback" target="_blank" style="text-decoration: none;">发表评论</a></div>
<br>文章来源:<a href="http://www.blogjava.net/kuxiaoku/articles/94806.html">http://www.blogjava.net/kuxiaoku/articles/94806.html</a> <img src ="http://www.blogjava.net/kuxiaoku/aggbug/107850.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:14 <a href="http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107850.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#实时申请技术（作者： crystal编译 出处： yesky）</title><link>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107851.html</link><dc:creator>苦笑枯</dc:creator><author>苦笑枯</author><pubDate>Thu, 18 Jan 2007 16:13:00 GMT</pubDate><guid>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107851.html</guid><wfw:comment>http://www.blogjava.net/kuxiaoku/comments/107851.html</wfw:comment><comments>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107851.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kuxiaoku/comments/commentRss/107851.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kuxiaoku/services/trackbacks/107851.html</trackback:ping><description><![CDATA[		<a class="bluekey" href="http://www.yesky.com/key/4733/164733.html" target="_blank">
<font size="1">Real</font>
</a>
<font size="1">
time Application
实时申请技术在本文里是作为一个实例来演示在用户（Tcpclient）申请与服务器（TcpServer）申请之间使用Socket类的情况
。该项目同样也演示在实时项目中如何使用listview控制以及如何传递XML格式信息。 <br><br>　　TcpServer.exe 文件显示了在单独的thread当中（而不是在</font>
<a class="bluekey" href="http://www.yesky.com/key/4326/169326.html" target="_blank">
<font size="1">GUI</font>
</a>
<font size="1"> 线程之中）TCP socket的相互通讯。<br><br>　　TcpClient.exe文件同样也使用一条单独的线程 从Socket中读取数据，然后对表单中的list </font>
<a class="bluekey" href="http://www.yesky.com/key/1638/206638.html" target="_blank">
<font size="1">view</font>
</a>
<font size="1">控件进行更新。<br><br>　　步聚如下：<br><br>　　1．TcpServer 监听端口8002，并且发射线程等待客户端连结。<br><br></font>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td height="504">
            <p>
            <font size="1">Hashtable socketHolder = new Hashtable(); <br><br>Hashtable threadHolder = new Hashtable();<br><br>public Form1() <br><br>{ <br><br>　// Required for Windows Form Designer support <br><br>　// <br><br>　InitializeComponent(); <br><br>　tcpLsn = new TcpListener(8002); <br><br>　tcpLsn.Start(); <br><br>　// tcpLsn.LocalEndpoint may have a bug, it only show 0.0.0.0:8002 <br><br>　stpanel.Text = "Listen at: " + tcpLsn.LocalEndpoint.</font>
            <a class="bluekey" href="http://www.yesky.com/key/2245/207245.html" target="_blank">
            <font size="1">ToString</font>
            </a>
            <font size="1">(); <br><br>　Thread tcpThd = new Thread(new ThreadStart(WaitingForClient)); <br><br>　threadHolder.</font>
            <a class="bluekey" href="http://www.yesky.com/key/4717/214717.html" target="_blank">
            <font size="1">Add</font>
            </a>
            <font size="1">(connectId, tcpThd); <br><br>　tcpThd.Start() ; <br><br>} </font>
            </p>
            <p>&nbsp;</p>
            <p>
            <font size="1">　2. TcpClient与TcpSrv连接上后，发送客户端信息数据包至TcpServer，然后发射线程，该线程是用来接收通过Socket传来的数据。<br><br></font>
            </p>
            <table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td>
                        <font size="1">private void menuConn_Click(object sender, System.EventArgs e) <br><br>{ <br>　ConnectDlg myDlg = new ConnectDlg(); <br><br>　myDlg.ShowDialog(this); <br><br>　if( myDlg.DialogResult==DialogResult.OK) <br><br>　{ <br><br>　　s = new Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp ); <br><br>　　IPAddress hostadd = IPAddress.Parse(myDlg.IpAdd); <br><br>　　int port=Int32.Parse(myDlg.PortNum); <br><br>　　IPEndPoint EPhost = new IPEndPoint(hostadd, port); <br><br>　　Try <br><br>　　{ <br><br>　　　s.Connect(EPhost); <br><br>　　　if (s.Connected) <br><br>　　　{ <br><br>　　　　Byte[] bBuf; <br><br>　　　　string buf; <br><br>　　　　buf = String.Format("{0}:{1}", myDlg.UserName,myDlg.PassWord); <br><br>　　　　bBuf=ASCII.GetBytes(buf); <br><br>　　　　s.Send(bBuf, 0 , bBuf.Length,0); <br><br>　　　　t = new Thread(new ThreadStart(StartRecieve)); <br><br>　　　　t.Start(); <br><br>　　　　sbar.Text="Ready to recieve data"; <br><br>　　　} <br><br>　　} <br><br>　　catch (Exception e1) <br><br>　　{ <br><br>　　　MessageBox.Show(e1.ToString()); <br><br>　　} <br><br>　} <br><br>} <br><br>private void StartRecieve() <br><br>{ <br><br>　miv = new MethodInvoker(this.UpdateListView); <br><br>　int cnt=0; <br><br>　string tmp=null; <br><br>　Byte[] firstb= new Byte[1]; <br><br>　while (true) <br><br>　{ <br><br>　　try <br><br>　　{ <br><br>　　　Byte[] receive = new Byte[1]; <br><br>　　　int ret = s.Receive(receive, 1, 0); <br><br>　　　if (ret &gt; 0) <br><br>　　　{ <br><br>　　　　switch(receive[0]) <br><br>　　　　{ <br><br>　　　　　case 11: //check start message <br><br>　　　　　　　cnt=0; <br><br>　　　　　　　break; <br><br>　　　　　case 10: // check end message <br><br>　　　　　　　cnt=0; <br><br>　　　　　　　if(firstb[0] == ':') <br><br>　　　　　　　　HandleCommand(tmp); <br><br>　　　　　　　else if(firstb[0] == '&lt;') <br><br>　　　　　　　　HandleXml(tmp); <br><br>　　　　　　　else <br><br>　　　　　　　　HandleText(tmp); <br><br>　　　　　　　　tmp=null; <br><br>　　　　　　　　break; <br><br>　　　　　　　default: <br><br>　　　　　　　　if (cnt == 0) <br><br>　　　　　　　　　firstb[0] = receive[0]; <br><br>　　　　　　　　　tmp += System.Text.Encoding <br><br>　　　　　　　　　.ASCII.GetString(receive);<br><br>　　　　　　　　　cnt++; <br><br>　　　　　　　　　break; <br><br>　　　　　　　　} <br><br>　　　　　　　} <br><br>　　　　} <br><br>　　　　catch (Exception e) <br><br>　　　　{ <br><br>　　　　　if( !s.Connected ) <br><br>　　　　　　{ <br><br>　　　　　　　break; <br><br>　　　　　　} <br><br>　　　　　} <br><br>　　　} <br><br>　　　t.Abort(); <br><br>　　} </font>
                        </td>
                    </tr>
                </tbody>
            </table>
            <p>&nbsp;</p>
            <p>&nbsp;</p>
            <p>
            <font size="1">　3.TcpServer接收来自TcpClient的连接请求，并且将socket 实例保存到Hash表中，然后发射线程以便控制socket的通讯，同时将客户端信息在listview 控件中显示出来。<br><br></font>
            </p>
            <table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
                <tbody>
                    <tr>
                        <td height="3552">
                        <p>
                        <font size="1">public void WaitingForClient() <br><br>{ <br><br>　while(true) <br><br>　{ <br><br>　　// Accept will block until someone connects <br><br>　　Socket sckt = tcpLsn.AcceptSocket(); <br><br>　　if (connectId &lt; 10000) <br><br>　　　Interlocked.Increment(ref connectId); <br><br>　　Else <br><br>　　　connectId = 1; <br><br>　　　if (socketHolder.Count &lt; MaxConnected ) <br>　<br>　　　{ <br><br>　　　　while (socketHolder.Contains(connectId) ) <br><br>　　　　{ <br><br>　　　　　Interlocked.Increment(ref connectId); <br><br>　　　　} <br><br>　　　Thread td = new Thread(new ThreadStart(ReadSocket)); <br><br>　　　lock(this) <br><br>　　　{ <br><br>　　　　// it is used to keep connected Sockets <br><br>　　　　socketHolder.Add(connectId, sckt); <br><br>　　　　// it is used to keep the active thread <br><br>　　　　threadHolder.Add(connectId, td); <br><br>　　　} <br><br>　　　td.Start(); <br><br>　　} <br><br>　} <br><br>} <br><br>// follow function handle the communication from the clients and close the <br><br>// socket and the thread when the socket connection is down <br><br>public void ReadSocket() <br><br>{ <br><br>　// the connectId is keeping changed with new connection added. it can't <br><br>　// be used to keep the real connectId, the local variable realId will <br><br>　// keep the value when the thread started. <br><br>　long realId = connectId; <br><br>　int ind=-1; <br><br>　Socket s = (Socket)socketHolder[realId]; <br><br>　while (true) <br><br>　{ <br><br>　　if(s.Connected) <br><br>　　{ <br><br>　　　Byte[] receive = new Byte[37] ; <br><br>　　　Try <br><br>　　　{ <br><br>　　　　// Receive will block until data coming <br><br>　　　　// ret is 0 or Exception happen when Socket connection<br><br>　　　　// is broken <br><br>　　　　int ret=s.Receive(receive,receive.Length,0); <br><br>　　　　if (ret &gt; 0) <br><br>　　　　{ <br><br>　　　　　string tmp = null; <br><br>　　　　　tmp=System.Text.Encoding.ASCII.GetString(receive);<br><br>　　　　　if(tmp.Length &gt; 0) <br><br>　　　　　{ <br><br>　　　　　　DateTime now1=DateTime.Now; <br><br>　　　　　　String strDate; <br><br>　　　　　　strDate = now1.ToShortDateString() + " " + now1.ToLongTimeString(); <br><br>　　　　　　ListViewItem newItem = new ListViewItem();<br><br>　　　　　　string[] strArry=tmp.Split(':'); <br><br>　　　　　　int code = checkUserInfo(strArry[0]); <br><br>　　　　　　if(code==2) <br><br>　　　　　　{ <br><br>　　　　　　　userHolder.Add(realId, strArry[0]); <br><br>　　　　　　　newItem.SubItems.Add(strArry[0]); <br><br>　　　　　　　newItem.ImageIndex = 0; <br><br>　　　　　　　newItem.SubItems.Add(strDate); <br><br>　　　　　　　this.listView2.Items.Add(newItem); <br><br>　　　　　　　ind=this.listView2.Items.IndexOf(newItem);<br><br>　　　　　　} <br><br>　　　　　　else if( code==1) <br><br>　　　　 } <br><br>　　　} <br><br>　　　else <br><br>　　　{ <br><br>　　　　this.listView2.Items[ind].ImageIndex=1; <br><br>　　　　keepUser=false; <br><br>　　　　break; <br><br>　　　} <br><br>　　} <br><br>　　catch (Exception e) <br><br>　　{ <br><br>　　　if( !s.Connected ) <br><br>　　　{ <br><br>　　　　this.listView2.Items[ind].ImageIndex=1; <br><br>　　　　keepUser=false; <br><br>　　　　break; <br><br>　　　} <br><br>　　} <br><br>　} <br><br>　} <br>　<br>　CloseTheThread(realId); <br><br>} <br><br>private void CloseTheThread(long realId) <br><br>{ <br><br>　socketHolder.Remove(realId); <br><br>　if(!keepUser) userHolder.Remove(realId); <br><br>　　lock(this) <br><br>　　{ <br><br>　　　Thread thd = (Thread)threadHolder[realId]; <br><br>　　　threadHolder.Remove(realId); <br><br>　　} <br><br>　　thd.Abort(); <br><br>　}</font>
                        </p>
                        <p>&nbsp;</p>
                        <p>&nbsp;</p>
                        <p>
                        <font size="1">4. 点击Load
                        Data菜单，从文件中载入信息，然后把所有信息传送到每个将与TcpServer相连接的客户端，客户端会自己更新它的listview。不管是
                        TcpServer 还是 TcpClient ，它们都从运作中的线程之中获取数据，再在主线程中更新Listview
                        control。下面则讲述的是通过MethodInvoker实现该功能。<br><br></font>
                        </p>
                        <table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
                            <tbody>
                                <tr>
                                    <td>
                                    <font size="1">public void LoadThread() <br><br>{ <br><br>MethodInvoker mi = new MethodInvoker(this.UpdateListView); <br><br>string tmp = null; <br><br>StreamReader sr = File.OpenText("Issue.txt"); <br><br>while((tmp = sr.ReadLine()) !=null ) <br><br>{ <br><br>if (tmp =="") <br><br>break; <br><br><br><br>isu.symbol= Mid(tmp, 0, 4); <br><br>isu.bid = Mid(tmp, 4, 5); <br><br>isu.offer = Mid(tmp, 9, 5); <br><br>isu.volume = Mid(tmp, 16, tmp.Length-16); <br><br><br><br>sendMsg ="\v" + tmp + "\n"; //add send message's head and end char<br><br>SendDataToAllClient(tmp); <br><br>this.BeginInvoke(mi); <br><br><br><br>JobDone.WaitOne(); <br><br>} <br><br>sr.Close(); <br><br>fThd.Abort(); <br><br>} <br><br>private void SendDataToAllClient(string str) <br><br>{ <br><br>foreach (Socket s in socketHolder.Values) <br><br>{ <br><br>if(s.Connected) <br><br>{ <br><br>Byte[] byteDateLine=ASCII.GetBytes(str.ToCharArray()); <br><br>s.Send(byteDateLine, byteDateLine.Length, 0); <br><br>} <br><br>} <br><br>} </font>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        <br>
                        <font size="1">　　以下代码 操纵XML文件，并且为客户端生成XML文件。<br><br></font>
                        <table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
                            <tbody>
                                <tr>
                                    <td>
                                    <font size="1">public void LoadXmlThread() <br><br>{ <br><br>MethodInvoker miv = new MethodInvoker(this.UpdateListView); <br><br>string tmp = null; <br><br>string xmlString = null; <br><br><br><br>int recordFlg = -1; <br><br>int textCount =0; <br><br>xmlString = "\v"+""; <br><br><br><br>XmlTextReader tr = new XmlTextReader("issue.xml"); <br><br>while(tr.Read()) <br><br>{ <br><br>switch (tr.NodeType) <br><br>{ <br><br>case XmlNodeType.Element: <br><br>if (tr.Name == "Issue") <br><br>{ <br><br>recordFlg++; <br><br>if(recordFlg &gt; 0) <br><br>{ <br><br>textCount=0; <br><br>xmlString += CreateXmlElement(<br><br>tr.Name, 2); <br><br>xmlString += "\n"; <br><br>SendDataToAllClient(xmlString);<br><br>xmlString = "\v"+" <br>version='1.0'?&gt;"; <br><br><br><br>this.BeginInvoke(miv); <br><br>JobDone.WaitOne(); <br><br>} <br><br>} <br><br>if (recordFlg &gt;= 0) <br><br>{ <br><br>xmlString += CreateXmlElement( <br><br>tr.Name, 1);<br><br>tmp = tr.Name; <br><br>} <br><br><br><br>break; <br><br>case XmlNodeType.Text: <br><br>switch(++textCount) <br><br>{ <br><br>case 1: <br><br>isu.symbol=tr.Value; <br><br>break; <br><br>case 2: <br><br>isu.bid=tr.Value; <br><br>break; <br><br>case 3: <br><br>isu.offer=tr.Value; <br><br>break; <br><br>case 4: <br><br>isu.volume=tr.Value; <br><br>break; <br><br>} <br><br>xmlString += tr.Value; <br><br>xmlString += CreateXmlElement(tmp, 2); <br><br>break; <br><br>} <br><br>} <br><br>fThd.Abort(); <br><br>} <br><br>string CreateXmlElement(string elem, int ord) <br><br>{ <br><br>string tmp = null; <br><br>if (ord == 1) <br><br>tmp = String.Format("&lt;{0}&gt;", elem); <br><br>else <br><br>tmp = String.Format("", elem); <br><br><br><br>return tmp; <br><br>} <br><br><br>以下功能演示的是如何设置TcpClient中Listview控件的 BackColor和 Forecolor属性 。<br>private void UpdateListView() <br><br>{ <br><br>int ind=-1; <br><br>for (int i=0; i &lt; this.listView1.Items.Count;i++) <br><br>{ <br><br>if (this.listView1.Items[i].Text == isu.symbol.ToString()) <br><br>{ <br><br>ind=i; <br><br>break; <br><br>} <br><br>} <br><br>if (ind == -1) <br><br>{ <br><br>ListViewItem newItem new ListViewItem(isu.symbol.ToString()); <br><br>newItem.SubItems.Add(isu.bid); <br><br>newItem.SubItems.Add(isu.offer); <br><br>newItem.SubItems.Add(isu.volume); <br><br><br><br>this.listView1.Items.Add(newItem); <br><br>int i=this.listView1.Items.IndexOf(newItem); <br><br>setRowColor(i, System.Drawing.Color.FromA#ffffaf); <br><br>setColColorHL(i, 0, System.Drawing.Color.FromA#800000); <br><br>setColColorHL(i, 1, System.Drawing.Color.FromA#800000); <br><br>this.listView1.Update(); <br><br>Thread.Sleep(300); <br><br>setColColor(i, 0, System.Drawing.Color.FromA#ffffaf); <br><br>setColColor(i, 1, System.Drawing.Color.FromA#ffffaf); <br><br>} <br><br>else <br><br>{ <br><br>this.listView1.Items[ind].Text = isu.symbol.ToString(); <br><br>this.listView1.Items[ind].SubItems[1].Text = (isu.bid); <br><br>this.listView1.Items[ind].SubItems[2].Text = (isu.offer); <br><br>this.listView1.Items[ind].SubItems[3].Text = (isu.volume); <br><br>setColColorHL(ind, 0, System.Drawing.Color.FromA#800000); <br><br>setColColorHL(ind, 1, System.Drawing.Color.FromA#800000); <br><br>this.listView1.Update(); <br><br>Thread.Sleep(300); <br><br>setColColor(ind, 0, System.Drawing.Color.FromA#ffffaf); <br><br>setColColor(ind, 1, System.Drawing.Color.FromA#ffffaf); <br><br>} <br><br>JobDone.Set(); <br><br>} <br><br><br><br>private void setRowColor(int rowNum, Color colr ) <br><br>{ <br><br>for (int i=0; i &lt; this.listView1.Items[rowNum].SubItems.Count;i++) <br><br>if (rowNum%2 !=0) <br><br>this.listView1.Items[rowNum].SubItems[i].BackColor = colr; <br><br>} <br><br><br><br>private void setColColor(int rowNum, int colNum, Color colr ) <br><br>{ <br><br>if (rowNum%2 !=0) <br><br>this.listView1.Items[rowNum].SubItems[colNum].BackColor=colr; <br><br>else <br><br>this.listView1.Items[rowNum].SubItems[colNum].BackColor = <br><br>System.Drawing.Color.FromA#f8f8f8; <br><br>if (colNum==0) <br><br>{ <br><br>this.listView1.Items[rowNum].SubItems[colNum].ForeColor = <br><br>System.Drawing.Color.FromA#800040; <br><br>this.listView1.Items[rowNum].SubItems[colNum].BackColor = <br><br>System.Drawing.Color.FromA#c5c5b6; <br><br>} <br><br>else <br><br>this.listView1.Items[rowNum].SubItems[colNum].ForeColor = <br><br>System.Drawing.Color.FromA#141414; <br><br>} <br><br><br><br>private void setColColorHL(int rowNum, int colNum, Color colr ) <br><br>{ <br><br>this.listView1.Items[rowNum].SubItems[colNum].BackColor = colr; <br><br>this.listView1.Items[rowNum].SubItems[colNum].ForeColor = <br><br>System.Drawing.Color.FromA#ffffff; <br><br>} </font>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        <br>
                        <font size="1">　　运行该例子的步骤<br><br>　　1. 在A机上运行TcpServer.exe文件。<br><br>　　2. 在A机或B机上运行一次或多次TcpClient.exe文件。<br><br>　　3. 在TcpClient端，点击菜单连接，进入TcpServer正在运行中的服务器端。在编辑栏键入用户名及口令，点击确认。<br><br>　　4. 当在TcpServer顶部的istview上瞧见客户端的提示时，则在TcpServer,上点击Load Data菜单，然后实时数据则会出现在TcpServer 和TcpClien上。<br><br>　　注意：请确认Data file, Issue.txt and Issue.xml等文件总是处于同一根目录下，正如TcpSvr.exe 和 MaskedTextBox.dll， WTcpClient.exe.是处于同一目录下一样。<br><br>　　Update at 10/20/2001. <br><br>　　当添加/删除项目时，请锁住Hash表，这样可以确保线程的安全。<br><br>　　添加功能，以便生成和处理XML格式文件。<br><br>　　在发送讯息至客户端时，请在服务器端添加发送讯息起始和结尾的字符。<br><br>　　上述方法可以增加客户端的稳定性。</font>
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<img src="http://www.blogjava.net/kuxiaoku/aggbug/94803.html" height="1" width="1"><br><br>
<div align="right"><a style="text-decoration: none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:13 <a href="http://www.blogjava.net/kuxiaoku/articles/94803.html#Feedback" target="_blank" style="text-decoration: none;">发表评论</a></div>
<br>文章来源:<a href="http://www.blogjava.net/kuxiaoku/articles/94803.html">http://www.blogjava.net/kuxiaoku/articles/94803.html</a> <img src ="http://www.blogjava.net/kuxiaoku/aggbug/107851.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:13 <a href="http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107851.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#：消息队列应用程序〔作者： Carl Nolan 出处： microsoft〕</title><link>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107852.html</link><dc:creator>苦笑枯</dc:creator><author>苦笑枯</author><pubDate>Thu, 18 Jan 2007 16:13:00 GMT</pubDate><guid>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107852.html</guid><wfw:comment>http://www.blogjava.net/kuxiaoku/comments/107852.html</wfw:comment><comments>http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107852.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kuxiaoku/comments/commentRss/107852.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kuxiaoku/services/trackbacks/107852.html</trackback:ping><description><![CDATA[		<span class="f14">
<font size="3">　<strong><font color="#ac0000">简介</font></strong><br><br>
Microsoft 近期推出了一种用于生成集成应用程序的新平台——Microsoft .NET 框架。.NET
框架允许开发人员使用任何编程语言迅速生成和部署 Web 服务和应用程序。Microsoft Intermediate Language
(MSIL) 和实时 (JIT) 编译器使这种不依赖语言的框架得以实现。 <br><br>　　与 .NET
框架同时面世的还有一种新的编程语言 C#（读作&#8220;C sharp&#8221;）。C# 是一种简单、新颖、面向对象和类型安全的编程语言。利用 .NET
框架和 C#（除 Microsoft? Visual Basic? 和 Managed C++ 之外），用户可以编写功能强大的
Microsoft Windows? 和 Web 应用程序及服务。本文提供了这样的一个解决方案，它的重点是 .NET 框架和 C#
而不是编程语言。C# 语言的介绍可以在&#8220; C# 简介和概述（英文）&#8221;找到。<br><br>　　近期的文章&#8220;MSMQ：可伸缩、高可用性的负载平衡解
决方案（英文）&#8221;介绍了一种解决方案，用于高可用性消息队列 (MSMQ) 的可伸缩负载平衡解决方案体系结构。此解决方案中涉及了一种将
Windows 服务用作智能消息路由器的开发方案。这样的解决方案以前只有 Microsoft Visual C++? 程序员才能实现，而
.NET 框架的出现改变了这种情况。从下面的解决方案中，您可以看到这一点。<br><br>　　.NET 框架应用程序<br><br>　　这里介绍
的解决方案是一种用来处理若干消息队列的 Windows
服务；其中每个队列都是由多个线程进行处理（接收和处理消息）。处理程序使用循环法技术或应用程序特定值（消息 AppSpecific
属性）从目的队列列表中路由消息，并使用消息属性来调用组件方法。（示例进程也属于这种情况。）在后一种情况下，组件的要求是它能够实现给定的接口
IWebMessage。要处理错误，应用程序需要将不能处理的消息发送到错误队列中。<br><br>　　消息应用程序的结构与以前的活动模板库
(ATL) 应用程序相似，它们之间的主要不同在于用于管理服务的代码的封装和 .NET 框架组件的使用。要创建 Windows 服务，.NET
框架用户仅仅需要创建一个从 ServiceBase（来自 System.ServiceControl 程序集）继承的类。这毫不奇怪，因为
.NET 框架是面向对象的。</font>
<br>
<font size="3">　<strong><font color="#ac0000">应用程序结构</font></strong><br><br>
应用程序中主要的类是 ServiceControl，它是从 ServiceBase 继承的。因而，它必须实现 OnStart 和
OnStop 方法，以及可选的 OnPause 和 OnContinue 方法。事实上，类是在静态方法 Main 内构造的：<br><br></font>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr bgcolor="#ffffff">
            <td>using System;<br>using System.ServiceProcess;<br><br>public class ServiceControl: ServiceBase<br>{<br>　// 创建服务对象的主入口点<br>　public static void Main()<br>　{<br>　　ServiceBase.Run(new ServiceControl());<br>　}<br><br>　// 定义服务参数的构造对象<br>　public ServiceControl()<br>　{<br>　　CanPauseAndContinue = true;<br>　　ServiceName = "MSDNMessageService";<br>　　AutoLog = false;<br>　}<br><br>　protected override void OnStart(string[] args) {...}<br>　protected override void OnStop() {...}<br>　protected override void OnPause() {...}<br>　protected override void OnContinue() {...}<br>}</td>
        </tr>
    </tbody>
</table>
<br>
ServiceControl 类创建一系列 CWorker 对象，即，为需要处理的每个消息队列创建 CWorker
类的一个实例。根据定义中处理队列所需的线程数目，CWorker 类依次创建了一系列的 CWorkerThread
对象。CWorkerThread 类创建的一个处理线程将执行实际的服务工作。<br><br>　　使用 CWorker 和 CWorkerThread 类的主要目的是确认服务控件 Start、Stop、Pause 和 Continue 命令。因为这些进程必须是无阻塞的，命令操作最终将在后台处理线程上执行。<br><br>
CWorkerThread 是一个抽象类，被 CWorkerThreadAppSpecific
、CWorkerThreadRoundRobin 和 CWorkerThreadAssembly
继承。这些类以不同的方式处理消息。前两个类通过给另一队列发送消息来处理消息（其不同之处在于确定接收队列路径的方式），最后一个类则使用消息属性来调
用组件方法。 <br><br>　　.NET 框架内部的错误处理是以基类 Exception
为基础的。当系统引发或捕获错误时，这些错误必须是从 Exception 中导出的类。CWorkerThreadException
类就是这样一种实现，它通过附加额外属性（用于定义服务是否应继续运行）来扩展基类。<br><br>　　最后，应用程序包含两种结构。这些值类型定义了辅助进程或线程的运行时参数，以简化 CWorker 和 CWorkerThread 对象的结构。使用值类型结构（而不是引用类型类）能够确保这些运行时参数维护的是数值（而不是引用）。<br><font size="3">　<strong><font color="#ac0000">IWebMessage 接口</font></strong><br><br>　　CWorkerThread 的实现之一是一个调用组件方法的类。这个名为 CWorkerThreadAssembly 的类使用 IWebMessage 接口来定义服务和组件之间的约定。<br><br>　　与当前版本的 Microsoft Visual Studio? 不同，C# 接口可以在任何语言中显式定义，而不需要创建和编译 IDL 文件。C# IWebMessage 接口的定义如下：<br><br></font>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>public interface IWebMessage<br>{<br>　WebMessageReturn Process(string sMessageLabel, string sMessageBody, int iAppSpecific);<br>　void Release();<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　ATL 代码中的 Process 方法是为处理消息而指定的。Process 方法的返回代码定义为枚举类型 WebMessageReturn：<br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>public enum WebMessageReturn <br>{<br>　ReturnGood,<br>　ReturnBad,<br>　ReturnAbort<br>}</td>
        </tr>
    </tbody>
</table>
<br><br>
枚举的定义如下：Good 表示继续处理，Bad 表示将消息写入错误队列，Abort 表示终止处理。Release
方法为服务提供了轻松清除类实例的途径。因为仅在垃圾回收的过程中才调用类实例的析构函数，所以确保所有占用昂贵资源（例如数据库连接）的类都有一个能够
在析构之前被调用的方法，用来释放这些资源，这是一种非常好的构思。<br><br>　　<strong><font color="#ac0000">名称空间</font></strong><br><br>
在这里先简单介绍一下名称空间。名称空间允许在内部和外部表示中将应用程序组织成为逻辑元素。服务内的所有代码都包含在
MSDNMessageService.Service
名称空间内。尽管服务代码包含在若干文件中，但是由于它们包含在同一名称空间中，因此用户不需要引用其他文件。<br><br>　　由于 IWebMessage 接口包含在 MSDNMessageService.Interface 名称空间中，因此使用此接口的线程类具有一个接口名称空间。<br><br>　　<strong><font color="#ac0000">服务类</font></strong><br><br>　　应用程序的目的是监视和处理消息队列，每一队列在收到消息时都执行不同的进程。应用程序是作为 Windows 服务来实现的。<br><font size="3"><strong><font color="#ac0000">　ServiceBase 类<br><br></font></strong>
如前所述，服务的基本结构是从 ServiceBase 继承的类。重要的方法包括 OnStart、OnStop、OnPause 和
OnContinue，每一个替代方法都与一个服务控制操作直接对应。OnStart 方法的目的是创建 CWorker 对象，而 CWorker
类又创建 CWorkerThread 对象，然后在该对象中创建执行服务工作的线程。<br><br>　　服务的运行时配置（以及 CWorker 和 CWorkerThread 对象的属性）是在基于 XML 的配置文件中维护的。它的名称与创建的 .exe 文件相同，但带有一个 .cfg 后缀。配置示例如下：<br><br></font>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>＜?xml version="1.0"?＞<br>＜configuration＞<br>＜ProcessList＞<br>　＜ProcessDefinition<br>　　　　ProcessName="Worker1"<br>　　　　ProcessDesc="Message Worker with 2 Threads"<br>　　　　ProcessType="AppSpecific"<br>　　　　ProcessThreads="2"<br>　　　　InputQueue=".\private$\test_load1"<br>　　　　ErrorQueue=".\private$\test_error"＞<br>　　＜OutputList＞<br>　　　＜OutputDefinition OutputName=".\private$\test_out11" /＞<br>　　　＜OutputDefinition OutputName=".\private$\test_out12" /＞<br>　　＜/OutputList＞<br>　＜/ProcessDefinition＞<br>　＜ProcessDefinition<br>　　　　ProcessName="Worker2"<br>　　　　ProcessDesc="Assembly Worker with 1 Thread"<br>　　　　ProcessType="Assembly"<br>　　　　ProcessThreads="1"<br>　　　　InputQueue=".\private$\test_load2"<br>　　　　ErrorQueue=".\private$\test_error"＞<br>　　＜OutputList＞<br>　　　＜OutputDefinition OutputName="C:\MSDNMessageService\MessageExample.dll" /＞<br>　　　＜OutputDefinition OutputName="MSDNMessageService.MessageSample.ExampleClass"/＞<br>　　＜/OutputList＞<br>　＜/ProcessDefinition＞<br>＜/ProcessList＞<br>＜/configuration＞</td>
        </tr>
    </tbody>
</table>
<br>
对此信息的访问通过来自 System.Configuration 程序集的 ConfigManager 类来管理。静态 Get
方法返回信息的集合，这些集合将被枚举以获得单个属性。这些属性集的设置决定了辅助对象的运行时特征。除了这一配置文件，您还应该创建定义 XML
文件结构的图元文件，并在其中引用位于服务器 machine.cfg 配置文件中的图元文件：<br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>＜?xml version ="1.0"?＞<br>＜MetaData xmlns="x-schema:CatMeta.xms"＞<br>　＜DatabaseMeta InternalName="MessageService"＞<br>　＜ServerWiring Interceptor="Core_XMLInterceptor"/＞<br>　＜Collection <br>　　　InternalName="Process" PublicName="ProcessList"<br>　　　PublicRowName="ProcessDefinition"<br>　　　SchemaGeneratorFlags="EMITXMLSCHEMA"＞<br>　　＜Property InternalName="ProcessName" Type="String" MetaFlags="PRIMARYKEY" /＞<br>　　＜Property InternalName="ProcessDesc" Type="String" /＞<br>　　＜Property InternalName="ProcessType" Type="Int32" DefaultValue="RoundRobin" ＞<br>　　　＜Enum InternalName="RoundRobin" Value="0"/＞<br>　　　＜Enum InternalName="AppSpecific" Value="1"/＞<br>　　　＜Enum InternalName="Assembly" Value="2"/＞<br>　　＜/Property＞<br>　　＜Property InternalName="ProcessThreads" Type="Int32" DefaultValue="1" /＞<br>　　＜Property InternalName="InputQueue" Type="String" /＞<br>　　＜Property InternalName="ErrorQueue" Type="String" /＞<br>　　＜Property InternalName="OutputName" Type="String" /＞<br>　　＜QueryMeta InternalName="All" MetaFlags="ALL" /＞<br>　　＜QueryMeta InternalName="QueryByFile" CellName="__FILE" Operator="EQUAL" /＞<br>　＜/Collection＞<br>　＜Collection <br>　　　InternalName="Output" PublicName="OutputList"<br>　　　PublicRowName="OutputDefinition"<br>　　　SchemaGeneratorFlags="EMITXMLSCHEMA"＞<br>　　＜Property InternalName="ProcessName" Type="String" MetaFlags="PRIMARYKEY" /＞<br>　　＜Property InternalName="OutputName" Type="String" MetaFlags="PRIMARYKEY" /＞<br>　　　＜QueryMeta InternalName="All" MetaFlags="ALL" /＞<br>　　　＜QueryMeta InternalName="QueryByFile" CellName="__FILE" Operator="EQUAL" /＞<br>　　＜/Collection＞<br>　＜/DatabaseMeta＞<br>　＜RelationMeta <br>　　　PrimaryTable="Process" PrimaryColumns="ProcessName"<br>　　　ForeignTable="Output" ForeignColumns="ProcessName"<br>　　　MetaFlags="USECONTAINMENT"/＞<br>＜/MetaData＞</td>
        </tr>
    </tbody>
</table>
</span>
<font size="3">由于 Service 类必须维护一个已创建辅助对象的列表，因此使用了 Hashtable 集合，用于保持类型对象的名称/数值对列表。Hashtable 不仅支持枚举，还允许通过关键字来查询值。在应用程序中，XML 进程名称是唯一的关键字：<br><br></font>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>private Hashtable htWorkers = new Hashtable();<br>IConfigCollection cWorkers = ConfigManager.Get("ProcessList", new AppDomainSelector());<br>foreach (IConfigItem ciWorker in cWorkers)<br>{<br>　WorkerFormatter sfWorker = new WorkerFormatter();<br>　sfWorker.ProcessName = (string)ciWorker["ProcessName"];<br>　sfWorker.ProcessDesc = (string)ciWorker["ProcessDesc"];<br>　sfWorker.NumberThreads = (int)ciWorker["ProcessThreads"];<br>　sfWorker.InputQueue = (string)ciWorker["InputQueue"];<br>　sfWorker.ErrorQueue = (string)ciWorker["ErrorQueue"];<br>　// 计算并定义进程类型<br>　switch ((int)ciWorker["ProcessType"])<br>　{<br>　　case 0:<br>　　　sfWorker.ProcessType = WorkerFormatter.SFProcessType.ProcessRoundRobin;<br>　　　break;<br>　　case 1:<br>　　　sfWorker.ProcessType = WorkerFormatter.SFProcessType.ProcessAppSpecific;<br>　　　break;<br>　　case 2:<br>　　　sfWorker.ProcessType = WorkerFormatter.SFProcessType.ProcessAssembly;<br>　　　break;<br>　　default:<br>　　throw new Exception("Unknown Processing Type");<br>　}<br>　// 执行更多的工作以读取输出信息<br>　string sProcessName = (string)ciWorker["ProcessName"];<br>　if (htWorkers.ContainsKey(sProcessName))<br>　　throw new ArgumentException("Process Name Must be Unique: " + sProcessName);<br>　　htWorkers.Add(sProcessName, new CWorker(sfWorker));<br>}</td>
        </tr>
    </tbody>
</table>
<br>
<br>　　在这段代码中没有包含的主要信息是输出数据的获取。每一个进程定义中都有一组相应的输出定义项。该信息是通过如下的简单查询读取的：<br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>string sQuery = "SELECT * FROM OutputList WHERE ProcessName=" + <br>sfWorker.ProcessName + " AND Selector=appdomain://";<br>ConfigQuery qQuery = new ConfigQuery(sQuery);<br>IConfigCollection cOutputs = ConfigManager.Get("OutputList", qQuery);<br>int iSize = cOutputs.Count, iLoop = 0;<br>sfWorker.OutputName = new string[iSize];<br>foreach (IConfigItem ciOutput in cOutputs)<br>sfWorker.OutputName[iLoop++] = (string)ciOutput["OutputName"];</td>
        </tr>
    </tbody>
</table>
<br>　　CWorkerThread 和 Cworker 类都有相应的服务控制方法，根据服务控制操作进行调用。由于 Hashtable 中引用了每一个 CWorker 对象，因此需要枚举 Hashtable 的内容，以调用适当的服务控制方法：<br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>foreach (CWorker cWorker in htWorkers.Values)<br>　cWorker.Start();</td>
        </tr>
    </tbody>
</table>
<br>　　类似地，实现的 OnPause、OnContinue 和 OnStop 方法是通过调用 CWorker 对象上的相应方法来执行操作的。<br><font size="3">　<strong><font color="#ac0000">CWorker 类</font></strong><br><br>
CWorker 类的主要功能是创建和管理 CWorkerThread 对象。Start、Stop、Pause 和 Continue
方法调用相应的 CWorkerThread 方法。实际的 CWorkerThread 对象是在Start 方法中创建的。与使用
Hashtable 管理辅助对象引用的 Service 类相似，CWorker 使用 ArrayList（简单的动态数组）来维护线程对象的列表。<br><br>　　在这个数组内部，CWorker 类创建了 CWorkerThread 类的一个实现版本。CWorkerThread 类（将在下面讨论）是一个必须继承的抽象类。导出类定义了消息的处理方式：<br><br></font>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>aThreads = new ArrayList();<br>for (int idx=0; idx＜sfWorker.NumberThreads; idx++)<br>{<br>　WorkerThreadFormatter wfThread = new WorkerThreadFormatter();<br>　wfThread.ProcessName = sfWorker.ProcessName;<br>　wfThread.ProcessDesc = sfWorker.ProcessDesc;<br>　wfThread.ThreadNumber = idx;<br>　wfThread.InputQueue = sfWorker.InputQueue;<br>　wfThread.ErrorQueue = sfWorker.ErrorQueue;<br>　wfThread.OutputName = sfWorker.OutputName;<br>　// 定义辅助类型，并将其插入辅助线程结构<br>　CWorkerThread wtBase;<br>　switch (sfWorker.ProcessType)<br>　{<br>　　case WorkerFormatter.SFProcessType.ProcessRoundRobin:<br>　　　wtBase = new CWorkerThreadRoundRobin(this, wfThread);<br>　　　break;<br>　　case WorkerFormatter.SFProcessType.ProcessAppSpecific:<br>　　　wtBase = new CWorkerThreadAppSpecific(this, wfThread);<br>　　　break;<br>　　case WorkerFormatter.SFProcessType.ProcessAssembly:<br>　　　wtBase = new CWorkerThreadAssembly(this, wfThread);<br>　　　break;<br>　　default:<br>　　　throw new Exception("Unknown Processing Type");<br>　}<br>　// 添加对数组的调用<br>　aThreads.Insert(idx, wtBase);<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　一旦所有的对象都已创建，就可以通过调用每个线程对象的 Start 方法来启动它们：<br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>foreach(CWorkerThread cThread in aThreads)<br>　cThread.Start();</td>
        </tr>
    </tbody>
</table>
<br>　　Stop、Pause 和 Continue 方法在 foreach 循环里执行的操作类似。Stop 方法具有如下的垃圾收集操作：<br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>GC.SuppressFinalize(this);</td>
        </tr>
    </tbody>
</table>
<p><br>　　在类析构函数中将调用 Stop 方法，这样，在没有显式调用 Stop 方法的情况下也可以正确地终止对象。如果调用了 Stop
方法，将不需要析构函数。SuppressFinalize 方法能够防止调用对象的 Finalize 方法（析构函数的实际实现）。</p>
<p><font size="3"><strong><font color="#ac0000">CWorkerThread 抽象类<br><br></font></strong>
CWorkerThread 是一个由 CWorkerThreadAppSpecifc、CWorkerThreadRoundRobin 和
CWorkerThreadAssembly 继承的抽象类。无论如何处理消息，队列的大部分处理是相同的，所以 CWorkerThread
类提供了这一功能。这个类提供了抽象方法（必须被实际方法替代）以管理资源和处理消息。<br><br>　　类的工作再一次通过 Start、Stop、Pause 和 Continue 方法来实现。在 Start 方法中引用了输入和错误队列。在 .NET 框架中，消息由 System.Messaging 名称空间处理：<br><br></font></p>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>// 尝试打开队列，并设置默认的读写属性<br>MessageQueue mqInput = new MessageQueue(sInputQueue);<br>mqInput.MessageReadPropertyFilter.Body = true;<br>mqInput.MessageReadPropertyFilter.AppSpecific = true;<br>MessageQueue mqError = new MessageQueue(sErrorQueue);<br>// 如果使用 MSMQ COM，则将格式化程序设置为 ActiveX<br>mqInput.Formatter = new ActiveXMessageFormatter();<br>mqError.Formatter = new ActiveXMessageFormatter();</td>
        </tr>
    </tbody>
</table>
<br>　　一旦定义了消息队列引用，即会创建一个线程用于实际的处理函数（称为 ProcessMessages）。在 .NET 框架中，使用 System.Threading 名称空间很容易实现线程处理：<br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>procMessage = new Thread(new ThreadStart(ProcessMessages));<br>procMessage.Start();</td>
        </tr>
    </tbody>
</table>
<br>　　ProcessMessages 函数是基于 Boolean 值的处理循环。当数值设为 False，处理循环将终止。因此，线程对象的 Stop 方法只设置这一 Boolean 值，然后关闭打开的消息队列，并加入带有主线程的线程：<br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>// 加入服务线程和处理线程<br>bRun = false;<br>procMessage.Join();<br>// 关闭打开的消息队列<br>mqInput.Close();<br>mqError.Close();</td>
        </tr>
    </tbody>
</table>
<br>　　Pause 方法只设置一个 Boolean 值，使处理线程休眠半秒钟：<br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>if (bPause) <br>　Thread.Sleep(500);</td>
        </tr>
    </tbody>
</table>
<br>　　最后，每一个 Start、Stop、Pause 和 Continue 方法将调用抽象的 OnStart、OnStop、OnPause 和 OnContinue 方法。这些抽象方法为实现的类提供了挂钩，以捕获和释放所需的资源。<br><br>　　ProcessMessages 循环具有如下基本结构：<br><br>　　　1、接收 Message。<br><br>　　　2、如果 Message 具有成功的 Receive，则调用抽象 ProcessMessage 方法。<br><br>　　　3、如果 Receive 或 ProcessMessage 失败，将 Message 发送至错误队列中。 <br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>Message mInput;<br>try<br>{<br>　// 从队列中读取，并等候 1 秒<br>　mInput = mqInput.Receive(new TimeSpan(0,0,0,1));<br>}<br>catch (MessageQueueException mqe)<br>{<br>　// 将消息设置为 null<br>　mInput = null;<br>　// 查看错误代码，了解是否超时<br>　if (mqe.ErrorCode != (-1072824293) ) //0xC00E001B<br>　{<br>　　// 如果未超时，发出一个错误并记录错误号<br>　　LogError("Error: " + mqe.Message);<br>　　throw mqe;<br>　}<br>}<br>if (mInput != null)<br>{<br>　// 得到一个要处理的消息，调用处理消息抽象方法<br>　try<br>　{<br>　　ProcessMessage(mInput);<br>　}<br>　// 捕获已知异常状态的错误<br>　catch (CWorkerThreadException ex)<br>　{<br>　　ProcessError(mInput, ex.Terminate);<br>　}<br>　// 捕获未知异常，并调用 Terminate<br>　catch<br>　{<br>　　ProcessError(mInput, true);<br>　}<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　ProcessError 方法将错误的消息发送至错误队列。另外，它也可能引发异常来终止线程。如果ProcessMessage 方法引发了终止错误或 CWorkerThreadException 类型，它将执行此操作。<br><font size="3"><strong><font color="#ac0000">CworkerThread 导出类<br><br></font></strong>
任何从 CWorkerThread 中继承的类都必须提供 OnStart、OnStop、OnPause、OnContinue 和
ProcessMessage 方法。OnStart 和 OnStop 方法获取并释放处理资源。OnPause 和 OnContinue
方法允许临时释放和重新获取这些资源。ProcessMessage 方法应该处理消息，并在出现失败事件时引发
CWorkerThreadException 异常。<br><br>　　由于 CWorkerThread 构造函数定义运行时参数，导出类必须调用基类构造函数：<br><br></font>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>public CWorkerThreadDerived(CWorker v_cParent, WorkerThreadFormatter v_wfThread)<br>: base (v_cParent, v_wfThread) {}</td>
        </tr>
    </tbody>
</table>
<br>
导出类提供了两种类型的处理：将消息发送至另一队列，或者调用组件方法。接收和发送消息的两种实现使用了循环技术或应用程序偏移（保留在消息
AppSpecific 属性中），作为使用哪一队列的决定因素。此方案中的配置文件应该包括队列路径的列表。实现的 OnStart 和
OnStop 方法应该打开和关闭对这些队列的引用：<br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>iQueues = wfThread.OutputName.Length;<br>mqOutput = new MessageQueue[iQueues];<br>for (int idx=0; idx＜iQueues; idx++)<br>{<br>　mqOutput[idx] = new MessageQueue(wfThread.OutputName[idx]);<br>　mqOutput[idx].Formatter = new ActiveXMessageFormatter();<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　在这些方案中，消息的处理很简单：将消息发送必要的输出队列。在循环情况下，这个进程为：<br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>try<br>{<br>　mqOutput[iNextQueue].Send(v_mInput);<br>}<br>catch (Exception ex)<br>{<br>　// 如果错误强制终止异常<br>　throw new CWorkerThreadException(ex.Message, true);<br>}<br>// 计算下一个队列号<br>iNextQueue++;<br>iNextQueue %= iQueues;</td>
        </tr>
    </tbody>
</table>
<br>　　后一种调用带消息参数的组件的实现方法比较有趣。ProcessMessage 方法使用 IWebMessage 接口调入一个 .NET 组件。OnStart 和 OnStop 方法获取和释放此组件的引用。<br><br>　　此方案中的配置文件应该包含两个项目：完整的类名和类所在文件的位置。按照 IWebMessage 接口中的定义，在组件上调用 Process 方法。<br><br>　　要获取对象引用，需要使用 Activator.CreateInstance 方法。此函数需要一个程序集类型。在这里，它是从程序集文件路径和类名中导出的。一旦获取对象引用，它将被放入合适的接口：<br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>private IWebMessage iwmSample;<br>private string sFilePath, sTypeName;<br>// 保存程序集路径和类型名称<br>sFilePath = wfThread.OutputName[0];<br>sTypeName = wfThread.OutputName[1];<br>// 获取对必要对象的引用<br>Assembly asmSample = Assembly.LoadFrom(sFilePath);<br>Type typSample = asmSample.GetType(sTypeName);<br>object objSample = Activator.CreateInstance(typSample);<br>// 定义给对象的必要接口<br>iwmSample = (IWebMessage)objSample;<br><br>获取对象引用后，ProcessMessage 方法将在 IWebMessage 接口上调用 Process 方法：<br><br>WebMessageReturn wbrSample;<br>try<br>{<br>　// 定义方法调用的参数<br>　string sLabel = v_mInput.Label;<br>　string sBody = (string)v_mInput.Body;<br>　int iAppSpecific = v_mInput.AppSpecific;<br>　// 调用方法并捕捉返回代码<br>　wbrSample = iwmSample.Process(sLabel, sBody, iAppSpecific);<br>}<br>catch (InvalidCastException ex)<br>{<br>　// 如果在消息内容中发生错误，则强制发出一个非终止异常<br>　throw new CWorkerThreadException(ex.Message, false);<br>}<br>catch (Exception ex)<br>{<br>　// 如果错误调用程序集，则强制发出终止异常<br>　throw new CWorkerThreadException(ex.Message, true);<br>}<br>// 如果没有错误，则检查对象调用的返回状态<br>switch (wbrSample)<br>{<br>　case WebMessageReturn.ReturnBad:<br>　　throw new CWorkerThreadException<br>　　　("Unable to process message: Message marked bad", false);<br>　case WebMessageReturn.ReturnAbort:<br>　　throw new CWorkerThreadException<br>　　　("Unable to process message: Process terminating", true);<br>　default:<br>　　break;<br>} </td>
        </tr>
    </tbody>
</table>
<br>　　提供的示例组件将消息正文写入数据库表。如果捕获到严重数据库错误，您可能希望终止处理过程，但是在这里，仅仅将消息标记为错误的消息。<br><br>　　由于此示例中创建的类实例可能会获取并保留昂贵的数据库资源，所以用 OnPause 和 OnContinue 方法释放和重新获取对象引用。<br><font size="3"><strong><font color="#ac0000">CworkerThread 导出类<br><br></font></strong>
任何从 CWorkerThread 中继承的类都必须提供 OnStart、OnStop、OnPause、OnContinue 和
ProcessMessage 方法。OnStart 和 OnStop 方法获取并释放处理资源。OnPause 和 OnContinue
方法允许临时释放和重新获取这些资源。ProcessMessage 方法应该处理消息，并在出现失败事件时引发
CWorkerThreadException 异常。<br><br>　　由于 CWorkerThread 构造函数定义运行时参数，导出类必须调用基类构造函数：<br><br></font>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>public CWorkerThreadDerived(CWorker v_cParent, WorkerThreadFormatter v_wfThread)<br>: base (v_cParent, v_wfThread) {}</td>
        </tr>
    </tbody>
</table>
<br>
导出类提供了两种类型的处理：将消息发送至另一队列，或者调用组件方法。接收和发送消息的两种实现使用了循环技术或应用程序偏移（保留在消息
AppSpecific 属性中），作为使用哪一队列的决定因素。此方案中的配置文件应该包括队列路径的列表。实现的 OnStart 和
OnStop 方法应该打开和关闭对这些队列的引用：<br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>iQueues = wfThread.OutputName.Length;<br>mqOutput = new MessageQueue[iQueues];<br>for (int idx=0; idx＜iQueues; idx++)<br>{<br>　mqOutput[idx] = new MessageQueue(wfThread.OutputName[idx]);<br>　mqOutput[idx].Formatter = new ActiveXMessageFormatter();<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　在这些方案中，消息的处理很简单：将消息发送必要的输出队列。在循环情况下，这个进程为：<br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>try<br>{<br>　mqOutput[iNextQueue].Send(v_mInput);<br>}<br>catch (Exception ex)<br>{<br>　// 如果错误强制终止异常<br>　throw new CWorkerThreadException(ex.Message, true);<br>}<br>// 计算下一个队列号<br>iNextQueue++;<br>iNextQueue %= iQueues;</td>
        </tr>
    </tbody>
</table>
<br>　　后一种调用带消息参数的组件的实现方法比较有趣。ProcessMessage 方法使用 IWebMessage 接口调入一个 .NET 组件。OnStart 和 OnStop 方法获取和释放此组件的引用。<br><br>　　此方案中的配置文件应该包含两个项目：完整的类名和类所在文件的位置。按照 IWebMessage 接口中的定义，在组件上调用 Process 方法。<br><br>　　要获取对象引用，需要使用 Activator.CreateInstance 方法。此函数需要一个程序集类型。在这里，它是从程序集文件路径和类名中导出的。一旦获取对象引用，它将被放入合适的接口：<br><br>
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td>private IWebMessage iwmSample;<br>private string sFilePath, sTypeName;<br>// 保存程序集路径和类型名称<br>sFilePath = wfThread.OutputName[0];<br>sTypeName = wfThread.OutputName[1];<br>// 获取对必要对象的引用<br>Assembly asmSample = Assembly.LoadFrom(sFilePath);<br>Type typSample = asmSample.GetType(sTypeName);<br>object objSample = Activator.CreateInstance(typSample);<br>// 定义给对象的必要接口<br>iwmSample = (IWebMessage)objSample;<br><br>获取对象引用后，ProcessMessage 方法将在 IWebMessage 接口上调用 Process 方法：<br><br>WebMessageReturn wbrSample;<br>try<br>{<br>　// 定义方法调用的参数<br>　string sLabel = v_mInput.Label;<br>　string sBody = (string)v_mInput.Body;<br>　int iAppSpecific = v_mInput.AppSpecific;<br>　// 调用方法并捕捉返回代码<br>　wbrSample = iwmSample.Process(sLabel, sBody, iAppSpecific);<br>}<br>catch (InvalidCastException ex)<br>{<br>　// 如果在消息内容中发生错误，则强制发出一个非终止异常<br>　throw new CWorkerThreadException(ex.Message, false);<br>}<br>catch (Exception ex)<br>{<br>　// 如果错误调用程序集，则强制发出终止异常<br>　throw new CWorkerThreadException(ex.Message, true);<br>}<br>// 如果没有错误，则检查对象调用的返回状态<br>switch (wbrSample)<br>{<br>　case WebMessageReturn.ReturnBad:<br>　　throw new CWorkerThreadException<br>　　　("Unable to process message: Message marked bad", false);<br>　case WebMessageReturn.ReturnAbort:<br>　　throw new CWorkerThreadException<br>　　　("Unable to process message: Process terminating", true);<br>　default:<br>　　break;<br>} </td>
        </tr>
    </tbody>
</table>
<br>　　提供的示例组件将消息正文写入数据库表。如果捕获到严重数据库错误，您可能希望终止处理过程，但是在这里，仅仅将消息标记为错误的消息。<br><br>　　由于此示例中创建的类实例可能会获取并保留昂贵的数据库资源，所以用 OnPause 和 OnContinue 方法释放和重新获取对象引用。<img src="http://www.blogjava.net/kuxiaoku/aggbug/94804.html" height="1" width="1"><br><br>
<div align="right"><a style="text-decoration: none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:13 <a href="http://www.blogjava.net/kuxiaoku/articles/94804.html#Feedback" target="_blank" style="text-decoration: none;">发表评论</a></div>
<br>文章来源:<a href="http://www.blogjava.net/kuxiaoku/articles/94804.html">http://www.blogjava.net/kuxiaoku/articles/94804.html</a> <img src ="http://www.blogjava.net/kuxiaoku/aggbug/107852.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kuxiaoku/" target="_blank">苦笑枯</a> 2007-01-19 00:13 <a href="http://www.blogjava.net/kuxiaoku/archive/2007/01/19/107852.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>