<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>『听风且吟』技术版 &#187; .NET</title>
	<atom:link href="http://coding.windstyle.cn/category/net/feed/" rel="self" type="application/rss+xml" />
	<link>http://coding.windstyle.cn</link>
	<description>Windie Chai&#039;s technique blog</description>
	<lastBuildDate>Tue, 07 Sep 2010 06:10:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>[C#]增强响应性，用加载窗体（Splash）来载入主窗体</title>
		<link>http://coding.windstyle.cn/2010/09/07/load-main-form-using-splash-form/</link>
		<comments>http://coding.windstyle.cn/2010/09/07/load-main-form-using-splash-form/#comments</comments>
		<pubDate>Tue, 07 Sep 2010 03:42:35 +0000</pubDate>
		<dc:creator>windie</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Splash]]></category>
		<category><![CDATA[加载]]></category>
		<category><![CDATA[可响应性]]></category>
		<category><![CDATA[线程]]></category>

		<guid isPermaLink="false">http://coding.windstyle.cn/?p=960</guid>
		<description><![CDATA[许多软件在启动的时候都会显示一个加载窗口（Splash），譬如微软的Visual Studio、Office以及Adobe的许多软件。这些加载窗口很精美，但“漂亮”并不是它们的主要作用。 设想一下用户双击了一个图标，等了许久都没有看到主窗体，就会感到迷惑：是不是刚才没有点中？于是又双击了一次，这次终于看到主窗体了，但看到了两个，因为启动了两次。 如果加载主窗体需要大量时间，那么在加载主窗体的同时去显示一个加载窗体就可以让用户知道软件已经响应了指令，并且正在进行处理，还可以告诉用户当前处理的进度，从而避免了用户的迷惑和误操作。 恰巧最近我的客户也有这样的抱怨，便研究了一下加载窗体的实现方法，顺便记录在这里以免遗忘。 那么就开始编写一个加载窗体吧。 我创建了一个很简单的窗体，它只包含一个Style=Marquee的ProgressBar（这个进度条会不断滚动），下面是它的代码以及注释： public partial class Splash : Form { public Splash() { InitializeComponent(); } //关闭自身 public void KillMe(object o, EventArgs e) { this.Close(); } /// &#60;summary&#62; /// 加载并显示主窗体 /// &#60;/summary&#62; /// &#60;param name=&#34;form&#34;&#62;主窗体&#60;/param&#62; public static void LoadAndRun(Form form) { //订阅主窗体的句柄创建事件 form.HandleCreated += delegate { //启动新线程来显示Splash窗体 new Thread(new ThreadStart(delegate { Splash [...]]]></description>
			<content:encoded><![CDATA[<p>许多软件在启动的时候都会显示一个加载窗口（Splash），譬如微软的Visual Studio、Office以及Adobe的许多软件。这些加载窗口很精美，但“漂亮”并不是它们的主要作用。<span id="more-960"></span></p>
<p>设想一下用户双击了一个图标，等了许久都没有看到主窗体，就会感到迷惑：是不是刚才没有点中？于是又双击了一次，这次终于看到主窗体了，但看到了两个，因为启动了两次。</p>
<p>如果加载主窗体需要大量时间，那么在加载主窗体的同时去显示一个加载窗体就可以让用户知道软件已经响应了指令，并且正在进行处理，还可以告诉用户当前处理的进度，从而避免了用户的迷惑和误操作。</p>
<p>恰巧最近我的客户也有这样的抱怨，便研究了一下加载窗体的实现方法，顺便记录在这里以免遗忘。</p>
<p>那么就开始编写一个加载窗体吧。</p>
<p>我创建了一个很简单的窗体，它只包含一个Style=Marquee的ProgressBar（这个进度条会不断滚动），下面是它的代码以及注释：</p>
<pre class="brush: csharp;">public partial class Splash : Form
{
public Splash()
{
InitializeComponent();
}

//关闭自身
public void KillMe(object o, EventArgs e)
{
this.Close();
}

/// &lt;summary&gt;
/// 加载并显示主窗体
/// &lt;/summary&gt;
/// &lt;param name=&quot;form&quot;&gt;主窗体&lt;/param&gt;
public static void LoadAndRun(Form form)
{
//订阅主窗体的句柄创建事件
form.HandleCreated += delegate
{
//启动新线程来显示Splash窗体
new Thread(new ThreadStart(delegate
{
Splash splash = new Splash();
//订阅主窗体的Shown事件
form.Shown += delegate
{
//通知Splash窗体关闭自身
splash.Invoke(new EventHandler(splash.KillMe));
splash.Dispose();
};
//显示Splash窗体
Application.Run(splash);

})).Start();
};
//显示主窗体
Application.Run(form);
}</pre>
<p>代码很好理解，Splash类只包含两个方法：一个普通的事件处理程序KillMe和一个静态方法LoadAndRun。</p>
<p>LoadAndRun方法用于加载并显示主窗体。在加载主窗体的同时，Splash窗体也会一直显示，直到主窗体加载完毕可以完全显示为止。</p>
<p>使用此加载窗体的方法也很简单，只需要把Program.cs中Main方法里的</p>
<pre class="brush: csharp;">Application.Run(new Form1());</pre>
<p>修改为</p>
<pre class="brush: csharp;">Splash.LoadAndRun(new Form1());</pre>
<p>即可。</p>
<p>如果想要看到效果，可以在Form1的OnLoad事件中让主线程睡一会儿觉，譬如：</p>
<pre class="brush: csharp;">protected override void OnLoad(EventArgs e)
{
System.Threading.Thread.Sleep(5000);
base.OnLoad(e);
}</pre>
<p>为什么要在新线程中显示加载窗体呢？因为忙碌的主窗体已经占有了主线程，如果把加载窗体也安排到主线程的话，它不仅很容易变成“失去响应”的状态，而且有可能连自身都无法顺利加载完，更别说不断滚动的进度条了。</p>
<p>另外，这种方法还有一个缺点，如果主窗体加载缓慢是因为在构造函数中执行了大量操作的话，那么这种方法就起不到作用了。</p>
<p>不过话说回来，在窗体的构造函数中执行影响性能的操作本来就是不被推荐的做法，应当尽量避免。</p>

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://coding.windstyle.cn/2008/09/02/invoke-javascript-method-in-activex-that-developing-using-csharp/" title="在用c#开发的ActiveX中调用JavaScript方法 (2008-09-02)">在用c#开发的ActiveX中调用JavaScript方法</a> (0)</li>
	<li><a href="http://coding.windstyle.cn/2008/06/17/csharp-process-lotus-notes-mail/" title="C#简单操作Lotus Notes邮件 (2008-06-17)">C#简单操作Lotus Notes邮件</a> (28)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://coding.windstyle.cn/2010/09/07/load-main-form-using-splash-form/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用c#来操作XML中的处理指令（PI）</title>
		<link>http://coding.windstyle.cn/2009/09/17/working-with-xml-processing-instructions/</link>
		<comments>http://coding.windstyle.cn/2009/09/17/working-with-xml-processing-instructions/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 01:00:46 +0000</pubDate>
		<dc:creator>windie</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[InfoPath]]></category>
		<category><![CDATA[PI]]></category>
		<category><![CDATA[prosessing instrucations]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[处理指令]]></category>

		<guid isPermaLink="false">http://coding.windstyle.cn/?p=294</guid>
		<description><![CDATA[什么是处理指令？处理指令（Processing Instructions，PI）是用“&#60;? ?&#62;”包围的一种标签，用以描述特定应用程序信息。Xml文档可以包含多个针对不同应用程序的处理指令。处理指令由两部分组成，target和value。target的角色类似于“名称”，紧随target之后的字符串就是value，value可以包含多个标记。 &#60;?target value?&#62; 那么Xml声明是不是处理指令呢？答案是肯定的，Xml声明是一个特殊的处理指令，它之所以特殊是因为它的value格式是预先定义好的。另外一个常见的处理指令示例是外部样式表。样式表处理指令也拥有预先定义好格式的value值，它由一些伪属性组成。为什么叫做“伪属性”，这是因为它的value值看上去像是几个正常的Xml属性，但事实上它们只是一个字符串而已。 &#60;?xml-stylesheet href=&#34;standardstyle.css&#34; title=&#34;Standard Stylesheet&#34; type=&#34;text/css&#34;?&#62; 然而处理指令value值的格式是开放的。处理指令并不是文档数据的一部分，Xml解析器并不会理会它的内容，而是直接将它传递给客户端应用程序。 微软Office套件中的InfoPath就是用了处理指令来指示Xml文件是否可以用InfoPath客户端来查看。 &#60;?mso-application progid=&#34;InfoPath.Document&#34;?&#62; 而另一个处理指令，mso-infoPathSolution，则告诉InfoPath解决方案模板的位置。该模板包含了布局Xml文件的布局转换信息、视图的架构信息已经数据源信息。 那么在c#应用程序中该如何操作包含处理指令的Xml文档呢？ 我们该如何处理和读取Xml文档中已有的处理指令？首先，处理指令可以像文档中的其他节点一样被选出。XPath使用了谓词（predicate ）processing-instruction()来测试该节点是不是一个处理指令。 在System.XML命名空间中，有一个XmlProcessingInstruction类。当你从Xml文档中选出了一个节点后，就可以把返回的XMLNode对象转换成这种类型，该类型提供了非常友好的接口来操作处理指令的value。想要读取它的value，只需要访问该对象的Value属性即可。 想要改变处理指令的值，也只需要将新值赋给该对象的Value属性。 想要在Xml文档中添加一个新的处理指令，可以使用XMLDocument类的CreateProcessingInstruction方法。然后再使用InsertBefore或InsertAfter方法来将这个XmlProcessingInstruction对象添加到Xml文档中。 想要从Xml文档中删除已有的处理指令，首先选出该处理指令的XmlNode对象，但不需要将其转换为XMLProcessingInstruction对象。然后使用XMLDocument类的RemoveChild方法就可以将其删除。 下面的代码包含了本文所提及的全部内容： // 显示Xml文档内容 Console.WriteLine(doc.InnerXml.ToString().Replace(&#34;&#62;&#60;&#34;, &#34;&#62;\r\n\n&#60;&#34;)); // 读取Xml文档的处理指令 XmlProcessingInstruction pi = (XmlProcessingInstruction)doc.SelectSingleNode(&#34;/processing-instruction(\&#34;mso-infoPathSolution\&#34;)&#34;); // 显示处理指令的value Console.WriteLine(pi.Value); // 更新处理指令的value pi.Value = &#34;updated value&#34;; // 显示更新后的处理指令value Console.WriteLine(pi.Value); // 创建新的处理指令 XmlProcessingInstruction piNew = doc.CreateProcessingInstruction(&#34;new-pi&#34;, &#34;my new processing instruction&#34;); // 将处理指令添加到文档中 doc.InsertBefore(piNew, doc.ChildNodes[3]); // 删除处理指令 XmlNode ndDel = doc.SelectSingleNode(&#34;/processing-instruction(\&#34;mso-application\&#34;)&#34;); doc.RemoveChild(ndDel); // 显示更改后的Xml文档 Console.WriteLine(doc.InnerXml.ToString().Replace(&#34;&#62;&#60;&#34;, &#34;&#62;\r\n\n&#60;&#34;)); [...]]]></description>
			<content:encoded><![CDATA[<p>什么是处理指令？处理指令（Processing Instructions，PI）是用“&lt;? ?&gt;”包围的一种标签，用以描述特定应用程序信息。Xml文档可以包含多个针对不同应用程序的处理指令。处理指令由两部分组成，target和value。target的角色类似于“名称”，紧随target之后的字符串就是value，value可以包含多个标记。</p>
<p><span id="more-294"></span></p>
<pre class="brush: xml;">&lt;?target value?&gt;</pre>
<p>那么Xml声明是不是处理指令呢？答案是肯定的，Xml声明是一个特殊的处理指令，它之所以特殊是因为它的value格式是预先定义好的。另外一个常见的处理指令示例是外部样式表。样式表处理指令也拥有预先定义好格式的value值，它由一些伪属性组成。为什么叫做“伪属性”，这是因为它的value值看上去像是几个正常的Xml属性，但事实上它们只是一个字符串而已。</p>
<pre class="brush: xml;">&lt;?xml-stylesheet href=&quot;standardstyle.css&quot; title=&quot;Standard Stylesheet&quot; type=&quot;text/css&quot;?&gt;</pre>
<p>然而处理指令value值的格式是开放的。处理指令并不是文档数据的一部分，Xml解析器并不会理会它的内容，而是直接将它传递给客户端应用程序。</p>
<p>微软Office套件中的InfoPath就是用了处理指令来指示Xml文件是否可以用InfoPath客户端来查看。</p>
<pre class="brush: xml;">&lt;?mso-application progid=&quot;InfoPath.Document&quot;?&gt;</pre>
<p>而另一个处理指令，mso-infoPathSolution，则告诉InfoPath解决方案模板的位置。该模板包含了布局Xml文件的布局转换信息、视图的架构信息已经数据源信息。</p>
<p>那么在c#应用程序中该如何操作包含处理指令的Xml文档呢？</p>
<p>我们该如何处理和读取Xml文档中已有的处理指令？首先，处理指令可以像文档中的其他节点一样被选出。XPath使用了谓词（predicate ）processing-instruction()来测试该节点是不是一个处理指令。</p>
<p>在System.XML命名空间中，有一个XmlProcessingInstruction类。当你从Xml文档中选出了一个节点后，就可以把返回的XMLNode对象转换成这种类型，该类型提供了非常友好的接口来操作处理指令的value。想要读取它的value，只需要访问该对象的Value属性即可。</p>
<p>想要改变处理指令的值，也只需要将新值赋给该对象的Value属性。</p>
<p>想要在Xml文档中添加一个新的处理指令，可以使用XMLDocument类的CreateProcessingInstruction方法。然后再使用InsertBefore或InsertAfter方法来将这个XmlProcessingInstruction对象添加到Xml文档中。</p>
<p>想要从Xml文档中删除已有的处理指令，首先选出该处理指令的XmlNode对象，但不需要将其转换为XMLProcessingInstruction对象。然后使用XMLDocument类的RemoveChild方法就可以将其删除。</p>
<p>下面的代码包含了本文所提及的全部内容：</p>
<pre class="brush: csharp;">// 显示Xml文档内容
Console.WriteLine(doc.InnerXml.ToString().Replace(&quot;&gt;&lt;&quot;, &quot;&gt;\r\n\n&lt;&quot;));
// 读取Xml文档的处理指令
XmlProcessingInstruction pi = (XmlProcessingInstruction)doc.SelectSingleNode(&quot;/processing-instruction(\&quot;mso-infoPathSolution\&quot;)&quot;);
// 显示处理指令的value
Console.WriteLine(pi.Value);

// 更新处理指令的value
pi.Value = &quot;updated value&quot;;

// 显示更新后的处理指令value
Console.WriteLine(pi.Value);

// 创建新的处理指令
XmlProcessingInstruction piNew = doc.CreateProcessingInstruction(&quot;new-pi&quot;, &quot;my new processing instruction&quot;);

// 将处理指令添加到文档中
doc.InsertBefore(piNew, doc.ChildNodes[3]);

// 删除处理指令
XmlNode ndDel = doc.SelectSingleNode(&quot;/processing-instruction(\&quot;mso-application\&quot;)&quot;);
doc.RemoveChild(ndDel);

// 显示更改后的Xml文档
Console.WriteLine(doc.InnerXml.ToString().Replace(&quot;&gt;&lt;&quot;, &quot;&gt;\r\n\n&lt;&quot;));</pre>
<p>本为翻译自：<a href="http://aspalliance.com/515_Working_with_XML_Processing_Instructions_in_C.all" target="_blank">http://aspalliance.com/515_Working_with_XML_Processing_Instructions_in_C.all</a></p>

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://coding.windstyle.cn/2010/01/24/sharepoint-2010-codeless-workflow-overview-2/" title="泛谈SharePoint 2010无代码工作流 (2010-01-24)">泛谈SharePoint 2010无代码工作流</a> (0)</li>
	<li><a href="http://coding.windstyle.cn/2007/01/08/sharepoint-workflow-tips-2-attention-of-first-sharepoint-workflow-development/" title="SharePoint工作流开发点滴(2)：开发第一个SharePiont工作流: HelloWorldSequential 的注意事项 (2007-01-08)">SharePoint工作流开发点滴(2)：开发第一个SharePiont工作流: HelloWorldSequential 的注意事项</a> (0)</li>
	<li><a href="http://coding.windstyle.cn/2009/01/16/infopath-developing-practice-1-intro/" title="InfoPath开发实战（1）：引言 (2009-01-16)">InfoPath开发实战（1）：引言</a> (0)</li>
	<li><a href="http://coding.windstyle.cn/2009/01/20/infopath-developing-practice-3-obtain-data-from-sql-server/" title="InfoPath开发实战（3）：获取SQL Server中的数据 (2009-01-20)">InfoPath开发实战（3）：获取SQL Server中的数据</a> (1)</li>
	<li><a href="http://coding.windstyle.cn/2007/01/16/sharepoint-workflow-tips-3-add-external-tools-to-help-developing-workflow/" title="SharePoint工作流开发点滴(3)：添加外部工具,方便工作流开发 (2007-01-16)">SharePoint工作流开发点滴(3)：添加外部工具,方便工作流开发</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://coding.windstyle.cn/2009/09/17/working-with-xml-processing-instructions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在用c#开发的ActiveX中调用JavaScript方法</title>
		<link>http://coding.windstyle.cn/2008/09/02/invoke-javascript-method-in-activex-that-developing-using-csharp/</link>
		<comments>http://coding.windstyle.cn/2008/09/02/invoke-javascript-method-in-activex-that-developing-using-csharp/#comments</comments>
		<pubDate>Tue, 02 Sep 2008 01:57:00 +0000</pubDate>
		<dc:creator>windie</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ActiveX]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[OC]]></category>

		<guid isPermaLink="false">http://coding.windstyle.cn/?p=233</guid>
		<description><![CDATA[这段时间要写一个ActiveX控件来控制扫描仪，并在扫描完成之后将文件路径通知页面。因为扫描的过程是异步的，所以我不能利用ActiveX控件公开的Scan方法来返回文件路径，结合Name Ctrl订阅联系人状态的思路，我想，如果可以用JavaScript来订阅ActiveX完成扫描的“事件”，我就可以在这个“事件”中把文件路径当作参数传递给页面了。 关于如何用c#开发ActiveX控件，红马天下兄的系列文章写的非常不错，我这里主要讲一下如何在ActiveX中调用页面上的JavaScript方法。 1.引用Microsoft.mshtml Microsoft.mshtml的路径是C:\Program Files\Microsoft.NET\Primary Interop Assemblies\Microsoft.mshtml.dll，添加引用后在ActiveX对应类中编写： using mshtml; 2.用c#实现两个COM类，IOleClientSite和IOleContainer [ComImport, Guid(&#34;00000118-0000-0000-C000-000000000046&#34;), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IOleClientSite { void SaveObject(); void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk); void GetContainer(out IOleContainer ppContainer); void ShowObject(); void OnShowWindow(bool fShow); void RequestNewObjectLayout(); } [ComImport, Guid(&#34;0000011B-0000-0000-C000-000000000046&#34;), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] public interface IOleContainer { void EnumObjects([In, MarshalAs(UnmanagedType.U4)] int grfFlags, [Out, MarshalAs(UnmanagedType.LPArray)] object[] ppenum); [...]]]></description>
			<content:encoded><![CDATA[<p>这段时间要写一个ActiveX控件来控制扫描仪，并在扫描完成之后将文件路径通知页面。因为扫描的过程是异步的，所以我不能利用ActiveX控件公开的Scan方法来返回文件路径，结合Name Ctrl订阅联系人状态的思路，我想，如果可以用JavaScript来订阅ActiveX完成扫描的“事件”，我就可以在这个“事件”中把文件路径当作参数传递给页面了。    <br />关于如何用c#开发ActiveX控件，<a href="http://www.cnblogs.com/homer">红马天下</a>兄的系列文章写的非常不错，我这里主要讲一下如何在ActiveX中调用页面上的JavaScript方法。</p>
<p> <span id="more-233"></span><br />
<h2>1.引用Microsoft.mshtml</h2>
<p>Microsoft.mshtml的路径是C:\Program Files\Microsoft.NET\Primary Interop Assemblies\Microsoft.mshtml.dll，添加引用后在ActiveX对应类中编写：</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">using mshtml;</div></div>
<h2>2.用c#实现两个COM类，IOleClientSite和IOleContainer</h2>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">[ComImport,<br />
Guid(&quot;00000118-0000-0000-C000-000000000046&quot;),<br />
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]<br />
public interface IOleClientSite<br />
{<br />
void SaveObject();<br />
void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);<br />
void GetContainer(out IOleContainer ppContainer);<br />
void ShowObject();<br />
void OnShowWindow(bool fShow);<br />
void RequestNewObjectLayout();<br />
}<br />
[ComImport,<br />
Guid(&quot;0000011B-0000-0000-C000-000000000046&quot;),<br />
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]<br />
public interface IOleContainer<br />
{<br />
void EnumObjects([In, MarshalAs(UnmanagedType.U4)] int grfFlags,<br />
[Out, MarshalAs(UnmanagedType.LPArray)] object[] ppenum);<br />
void ParseDisplayName([In, MarshalAs(UnmanagedType.Interface)] object pbc,<br />
[In, MarshalAs(UnmanagedType.BStr)] string pszDisplayName,<br />
[Out, MarshalAs(UnmanagedType.LPArray)] int[] pchEaten,<br />
[Out, MarshalAs(UnmanagedType.LPArray)] object[] ppmkOut);<br />
void LockContainer([In, MarshalAs(UnmanagedType.I4)] int fLock);<br />
}</div></div>
<h2>3.调用JavaScript方法</h2>
<p>在Activex控件的对应类中就可以编写如下的CallJavaScript方法：</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">private void CallJavaScript(string Filenames)<br />
{<br />
Type typeIOleObject = this.GetType().GetInterface(&quot;IOleObject&quot;,true);<br />
object oleClientSite = typeIOleObject.InvokeMember(&quot;GetClientSite&quot;,<br />
BindingFlags.Instance|BindingFlags.InvokeMethod|BindingFlags.Public,<br />
null,<br />
this,<br />
null);<br />
IOleClientSite oleClientSite2 = oleClientSite as IOleClientSite;<br />
IOleContainer pObj;<br />
oleClientSite2.GetContainer(out pObj);<br />
//参数数组<br />
object[] args = new object[1];<br />
args[0] = Filenames;<br />
//获取页面的Script集合<br />
IHTMLDocument pDoc2 = (IHTMLDocument)pObj;<br />
object script = pDoc2.Script;<br />
try<br />
{<br />
//调用JavaScript方法OnScaned并传递参数，因为此方法可能并没有在页面中实现，所以要进行异常处理<br />
script.GetType().InvokeMember(&quot;OnScaned&quot;,<br />
BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,<br />
null,<br />
script,<br />
args);<br />
}<br />
catch { }<br />
}</div></div>
<h2>4.在页面中实现相应的JavaScript方法</h2>
<p>在包含这个ActiveX控件的页面中添加如下的JavaScript方法： </p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">function OnScaned(files)<br />
{<br />
if(files)<br />
{<br />
//do something<br />
}<br />
}</div></div>
<p>这样，在ActiveX控件中调用CallJavaScript方法时，最终就会调用到页面中的OnScaned方法，藉此实现了ActiveX的“事件”机制。<br />
  <br />在测试的过程中发现一些有趣的事情，不妨也和大家分享一下： </p>
<ol>
<li>object元素的结束：object元素只能以&lt;object&gt;&lt;/object&gt;的方式结束，而不能简单的用&lt;object/&gt;来结束，这样结束的后果是object后边的元素都无法在JavaScript方法中获取，可能是浏览器还认为object元素没有结束吧。
<li>参数的类型：最初我想在c#中给JavaScript方法传递数组类型的参数，但当JavaScript方法执行时，我发现JavaScript将该参数识别为“unknown”，并且无法对其做任何处理，所以最后只好作罢，用传递以“|”分隔的字符串代替。
<li><a href="http://www.cnblogs.com/liubiqu/articles/92632.html">小草的这篇文章</a>提供了更简单的调用JavaScript方法，只需要在初始化时传递页面的window属性，但我还没弄清楚如何给JavaScript传递参数。
</li>
</ol>

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://coding.windstyle.cn/2008/03/28/fix-mouse-event-interference-of-html-inner-elements/" title="解决HTML内部元素的Mouse事件干扰 (2008-03-28)">解决HTML内部元素的Mouse事件干扰</a> (18)</li>
	<li><a href="http://coding.windstyle.cn/2009/04/09/css-naked-day/" title="CSS裸奔日 (2009-04-09)">CSS裸奔日</a> (0)</li>
	<li><a href="http://coding.windstyle.cn/2008/06/17/csharp-process-lotus-notes-mail/" title="C#简单操作Lotus Notes邮件 (2008-06-17)">C#简单操作Lotus Notes邮件</a> (28)</li>
	<li><a href="http://coding.windstyle.cn/2010/09/07/load-main-form-using-splash-form/" title="[C#]增强响应性，用加载窗体（Splash）来载入主窗体 (2010-09-07)">[C#]增强响应性，用加载窗体（Splash）来载入主窗体</a> (0)</li>
	<li><a href="http://coding.windstyle.cn/2007/06/08/ajax-net-1-0-fix-cross-domain-acess-error/" title="Ajax.net 1.0跨域访问错误的解决方法 (2007-06-08)">Ajax.net 1.0跨域访问错误的解决方法</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://coding.windstyle.cn/2008/09/02/invoke-javascript-method-in-activex-that-developing-using-csharp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C#简单操作Lotus Notes邮件</title>
		<link>http://coding.windstyle.cn/2008/06/17/csharp-process-lotus-notes-mail/</link>
		<comments>http://coding.windstyle.cn/2008/06/17/csharp-process-lotus-notes-mail/#comments</comments>
		<pubDate>Mon, 16 Jun 2008 17:10:00 +0000</pubDate>
		<dc:creator>windie</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Lotus Notes]]></category>
		<category><![CDATA[邮件]]></category>

		<guid isPermaLink="false">http://1223439</guid>
		<description><![CDATA[前段时间简单的研究了一下.NET操作Lotus Notes邮件的实现，具体的操作包括邮件的读取和发送，而且都要包含附件，其间参考了《在 Microsoft .NET 应用程序中使用 IBM Lotus Domino》一文，现在把成果和大家分享一下。 本文将分为获取用户列表、发送邮件、收取邮件三个部分，并会在文末提供范例程序（Visual Studio 2008）的下载。 引用 如果想使用.NET操作Lotus，我们可以使用 Lotus Domino Objects 通过 COM 来访问 Domino 对象，在 Domino 服务器或者任何一个 Notes 客户机（IBM Lotus Domino Designer、Lotus Domino Administrator 或者 Lotus Notes）的安装中都包括 Lotus Domino Objects。如果你的开发环境复合上述的要求，就可以添加一个COM引用：Lotus Domino Objects，然后： using Domino; &#160; 如果找不到这个COM组件，可以先注册以下组件，然后就可以找到了： regsvr32 &#34;C:\Program Files\lotus\notes\nlsxbe.dll&#34; &#160; 获取Notes邮箱用户列表 本段代码将遍历用户视图（People View）中的所有用户，将其全名添加到ComboBox控件中。新建两个全局变量（全局的目的是供本例中的其它方法使用）。 NotesSession ns; NotesDatabase ndb; &#160; &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>前段时间简单的研究了一下.NET操作Lotus Notes邮件的实现，具体的操作包括邮件的读取和发送，而且都要包含附件，其间参考了《<a href="http://www.ibm.com/developerworks/cn/lotus/domino-msnet/" target="_blank">在 Microsoft .NET 应用程序中使用 IBM Lotus Domino</a>》一文，现在把成果和大家分享一下。</p>
<p>本文将分为获取用户列表、发送邮件、收取邮件三个部分，并会在文末提供范例程序（Visual Studio 2008）的下载。 <span id="more-698"></span></p>
<h2>引用</h2>
<p>如果想使用.NET操作Lotus，我们可以使用 Lotus Domino Objects 通过 COM 来访问 Domino 对象，在 Domino 服务器或者任何一个 Notes 客户机（IBM Lotus Domino Designer、Lotus Domino Administrator 或者 Lotus Notes）的安装中都包括 Lotus Domino Objects。如果你的开发环境复合上述的要求，就可以添加一个COM引用：Lotus Domino Objects，然后：</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">using Domino;</div></div>
<p>&nbsp;</p>
<p>如果找不到这个COM组件，可以先注册以下组件，然后就可以找到了：</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">regsvr32 &quot;C:\Program Files\lotus\notes\nlsxbe.dll&quot;</div></div>
<p>&nbsp;</p>
<h2>获取Notes邮箱用户列表</h2>
<p>本段代码将遍历用户视图（People View）中的所有用户，将其全名添加到ComboBox控件中。新建两个全局变量（全局的目的是供本例中的其它方法使用）。</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">NotesSession ns;<br />
NotesDatabase ndb;</div></div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>发送邮件</h2>
<p>本段代码降为从ComboBox中选中的用户发送一封邮件，我们可以输入邮件的标题和内容，并可以添加附件。</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">try<br />
{<br />
&nbsp; &nbsp; if(ns!=null)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; NotesDocument doc = ndb.CreateDocument();<br />
&nbsp; &nbsp; &nbsp; &nbsp; doc.ReplaceItemValue(<br />
&quot;Form&quot;, &quot;Memo&quot;);<br />
<br />
//收件人信息<br />
&nbsp; &nbsp; &nbsp; &nbsp; doc.ReplaceItemValue(&quot;SendTo&quot;, cb_People.Text);<br />
<br />
//邮件主题<br />
&nbsp; &nbsp; &nbsp; &nbsp; doc.ReplaceItemValue(&quot;Subject&quot;, tb_Subject.Text);<br />
<br />
//邮件正文<br />
&nbsp; &nbsp; &nbsp; &nbsp; NotesRichTextItem rt = doc.CreateRichTextItem(&quot;Body&quot;);<br />
&nbsp; &nbsp; &nbsp; &nbsp; rt.AppendText(tb_Body.Text);<br />
<br />
//附件<br />
&nbsp; &nbsp; &nbsp; &nbsp; if (!string.IsNullOrEmpty(tb_Attachment.Text))<br />
&nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NotesRichTextItem attachment = doc.CreateRichTextItem(&quot;attachment&quot;);<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; attachment.EmbedObject(EMBED_TYPE.EMBED_ATTACHMENT, &quot;&quot;, tb_Attachment.Text, &quot;attachment&quot;);<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
<br />
//发送邮件<br />
&nbsp; &nbsp; &nbsp; &nbsp; object obj = doc.GetItemValue(&quot;SendTo&quot;);<br />
&nbsp; &nbsp; &nbsp; &nbsp; doc.Send(false,ref obj);<br />
&nbsp; &nbsp; &nbsp; &nbsp; doc = null;<br />
&nbsp; &nbsp; &nbsp; &nbsp; MessageBox.Show(&quot;Successfully!&quot;);<br />
&nbsp; &nbsp; }<br />
}<br />
catch(Exception ex)<br />
{<br />
&nbsp; &nbsp; MessageBox.Show(&quot;Error:&quot; + ex.Message);<br />
}</div></div>
<p>如果想要添加多个收件人，可以将代码：</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">doc.ReplaceItemValue(&quot;SendTo&quot;, cb_People.Text);</div></div>
<p>更改为代码：</p>
<p>&nbsp;</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">string[] receivers = { cb_People.SelectedItem.ToString(), &quot;windie chai/TEST&quot; };<br />
doc.ReplaceItemValue(&quot;SendTo&quot;, receivers);</div></div>
<p>如果想要添加多个附件，可以继续调用这个对象的EmbedObject方法:</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">attachment.EmbedObject(EMBED_TYPE.EMBED_ATTACHMENT, &quot;&quot;, &quot;FilePath&quot;, &quot;attachment&quot;);</div></div>
<p>&nbsp;</p>
<h2>获取收件箱内全部邮件</h2>
<p>为了存储邮件内容，我编写了一个简单的类：</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">/// &lt;summary&gt;<br />
/// 简单的邮件类<br />
/// &lt;/summary&gt;<br />
public class Mail<br />
{<br />
&nbsp;/// &lt;summary&gt;<br />
&nbsp;/// 主题<br />
&nbsp;/// &lt;/summary&gt;<br />
&nbsp;public string Subject<br />
&nbsp;{<br />
&nbsp;get { return _subject; }<br />
&nbsp;set { _subject = value; }<br />
&nbsp; &nbsp; }<br />
&nbsp;private string _subject = string.Empty;<br />
<br />
&nbsp;/// &lt;summary&gt;<br />
&nbsp;/// 发件者<br />
&nbsp;/// &lt;/summary&gt;<br />
&nbsp;public string From<br />
&nbsp;{<br />
&nbsp;get { return _from; }<br />
&nbsp;set { _from = value; }<br />
&nbsp; &nbsp; }<br />
&nbsp;private string _from = string.Empty;<br />
<br />
&nbsp;/// &lt;summary&gt;<br />
&nbsp;/// 邮件正文<br />
&nbsp;/// &lt;/summary&gt;<br />
&nbsp;public string Body<br />
&nbsp;{<br />
&nbsp;get { return _body; }<br />
&nbsp;set { _body = value; }<br />
&nbsp; &nbsp; }<br />
&nbsp;private string _body = string.Empty;<br />
<br />
&nbsp;/// &lt;summary&gt;<br />
&nbsp;/// 发件时间<br />
&nbsp;/// &lt;/summary&gt;<br />
&nbsp;public string Time<br />
&nbsp;{<br />
&nbsp;get { return _time; }<br />
&nbsp;set { _time = value; }<br />
&nbsp; &nbsp; }<br />
&nbsp;private string _time = string.Empty;<br />
<br />
&nbsp;/// &lt;summary&gt;<br />
&nbsp;/// 附件集合<br />
&nbsp;/// &lt;/summary&gt;<br />
&nbsp;public List Files<br />
&nbsp;{<br />
&nbsp;get { return _files; }<br />
&nbsp;set { _files = value; }<br />
&nbsp; &nbsp; }<br />
&nbsp;private List _files = new List();<br />
}</div></div>
<p>接着添加一个全局变量来存储邮件集合：</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">public List mails = new List();</div></div>
<p>然后将所有邮件的信息添加的mails集合中，并将它们的标题添加到一个ListBox中。</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">//清空邮件列表<br />
<br />
lb_Mail.Items.Clear();<br />
<br />
mails.Clear();<br />
<br />
<br />
<br />
//获取邮箱视图<br />
<br />
NotesDbDirectory dir = ns.GetDbDirectory(&quot;DominoT/TEST&quot;);<br />
<br />
NotesDatabase maildb = dir.OpenMailDatabase();<br />
<br />
NotesView nv = maildb.GetView(&quot;$inbox&quot;);<br />
<br />
<br />
<br />
//遍历所有邮件<br />
<br />
NotesDocument doc = nv.GetFirstDocument();<br />
<br />
while (doc != null)<br />
{<br />
&nbsp; &nbsp; Mail mail = new Mail();<br />
&nbsp; &nbsp; mail.Subject = ((object[])doc.GetItemValue(&quot;Subject&quot;))[0].ToString();<br />
&nbsp; &nbsp; mail.From = ((object[])doc.GetItemValue(&quot;From&quot;))[0].ToString();<br />
&nbsp; &nbsp; mail.Body = ((object[])doc.GetItemValue(&quot;Body&quot;))[0].ToString();<br />
&nbsp; &nbsp; mail.Time = ((object[])doc.GetItemValue(&quot;PostedDate&quot;))[0].ToString();<br />
&nbsp; &nbsp; object[] items = (object[])doc.Items;<br />
&nbsp; &nbsp; foreach (NotesItem item in items)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; if (item.Name == &quot;$FILE&quot;)<br />
&nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; string fileName = ((object[])item.Values)[0].ToString();<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NotesEmbeddedObject file = (NotesEmbeddedObject)doc.GetAttachment(fileName);<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (file != null)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mail.Files.Add(file);<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; mails.Add(mail);<br />
&nbsp; &nbsp; lb_Mail.Items.Add(mail.Subject);<br />
<br />
//查找下一封邮件<br />
&nbsp; &nbsp; doc = nv.GetNextDocument(doc);<br />
}</div></div>
<p>&nbsp;</p>
<h2>显示邮件内容并打开附件</h2>
<p>由于前面的代码中我已经把邮件信息添加到自己定义的邮件集合中了，所以下面的操作就不需要和Domino服务器交互了。</p>
<p>本段代码实现了在ListBox中点击邮件标题后在一个TextBox中显示邮件内容（包括标题，时间，正文和附件文件名）。</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Mail m = mails[lb_Mail.SelectedIndex];<br />
StringBuilder sbMail = new StringBuilder();<br />
sbMail.AppendLine(m.Subject);<br />
sbMail.AppendLine(&quot;----------&quot;);<br />
sbMail.AppendLine(m.Time);<br />
sbMail.AppendLine(&quot;----------&quot;);<br />
sbMail.AppendLine(m.Body);<br />
sbMail.AppendLine(&quot;----------&quot;);<br />
sbMail.AppendLine(&quot;Attachments:&quot;);<br />
foreach (NotesEmbeddedObject file in m.Files)<br />
{<br />
&nbsp; &nbsp; sbMail.AppendLine(file.Name);<br />
}<br />
tb_Mail.Text = sbMail.ToString();<br />
<br />
//根据附件数量决定打开附件按钮是否可用<br />
if(m.Files.Count&amp;gt;0)<br />
{<br />
&nbsp; &nbsp; btn_OpenAttachment.Enabled = true;<br />
}<br />
else<br />
&nbsp; &nbsp; btn_OpenAttachment.Enabled = false;</div></div>
<p>本段代码实现了当点击“打开附件”按钮后从内从中释放附件文件到硬盘并执行它。</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Mail m = mails[lb_Mail.SelectedIndex];<br />
<br />
//获取第一个附件<br />
NotesEmbeddedObject file = m.Files[0];<br />
<br />
//组合一个临时路径<br />
string filename = Path.Combine(Application.StartupPath,file.Name);<br />
<br />
//将附件释放到临时路径<br />
file.ExtractFile(filename);<br />
<br />
//执行附件<br />
System.Diagnostics.Process.Start(filename);</div></div>
<p>主要的代码就这么多了，第一次使用IBM的软件，感觉……很不顺手，连对象模型都相当别扭，嗯，废话不说了 ，如果上面的代码有何不恰当的地方还请各位朋友多多指教。</p>
<p><strong><a href="http://coding.windstyle.cn/files/2008/06/DominoTest.zip"><strong>点击这里</strong></a></strong>下载本文的范例程序（Visual Studio 2008），范例程序的UI如下：</p>
<p><img src="http://coding.windstyle.cn/files/cnblogs/DominoTestApp.png" border="0" alt="" /></p>
<p>点击“Sender”之后回到Notes中，刷新发现邮件已经收到，包含附件，并且可以正常打开：</p>
<p><img src="http://coding.windstyle.cn/files/cnblogs/DominoNotes.png" border="0" alt="" /></p>

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://coding.windstyle.cn/2010/09/07/load-main-form-using-splash-form/" title="[C#]增强响应性，用加载窗体（Splash）来载入主窗体 (2010-09-07)">[C#]增强响应性，用加载窗体（Splash）来载入主窗体</a> (0)</li>
	<li><a href="http://coding.windstyle.cn/2008/09/02/invoke-javascript-method-in-activex-that-developing-using-csharp/" title="在用c#开发的ActiveX中调用JavaScript方法 (2008-09-02)">在用c#开发的ActiveX中调用JavaScript方法</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://coding.windstyle.cn/2008/06/17/csharp-process-lotus-notes-mail/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>动态创建的TabContainer及其AutoPostBack</title>
		<link>http://coding.windstyle.cn/2007/06/25/create-tabcontainer-dynamicly-and-set-autopostback/</link>
		<comments>http://coding.windstyle.cn/2007/06/25/create-tabcontainer-dynamicly-and-set-autopostback/#comments</comments>
		<pubDate>Mon, 25 Jun 2007 02:18:00 +0000</pubDate>
		<dc:creator>windie</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[ajax.net]]></category>
		<category><![CDATA[AutoPostBack]]></category>
		<category><![CDATA[TabContainer]]></category>
		<category><![CDATA[事件]]></category>

		<guid isPermaLink="false">http://795334</guid>
		<description><![CDATA[&#160; 最近一直在解决这样一个问题. 我的页面布局如下图: 其中,TabPanel是在Page_LoadComplete事件中动态创建的,采用此事件的原因是我想让用户先可以看到页面中的其它内容. TabContainer的AutoPostBack设置为True,为每个TabPanel载入相应的内容. TabPanel创建成功后,点击TabPanel的Header部分,就会弹出这样的错误: Specified argument was out of the range of valid values. Parameter name: index 而且测试时发现TabContainer的Client与Server事件均没有被触发. 又经过一番测试,终于发现,因为PostBack时触发的事件顺序是: Page_Init &#62; Page_Load &#62; Page_LoadComplete &#62; ControlEvent &#62; Page_Unload. 由于我的TabPanel是在Page_LoadComplete事件中动态创建的,所以在所以Page_Init事件时,页面中根本就没有任何TabPanel,自然也就找不到对应的index. 把动态创建TabPanel的方法写道Page_Init事件中就可以解决这个问题. Related posts 《WF编程》系列之26 &#8211; 基本活动:ParallelActivity &#38; DelayActivity &#38; ListenActivity (8) 《WF编程》系列之19 &#8211; 触发事件与调用方法:服务以及工作流的实现 (10) 《WF编程》系列之18 &#8211; 触发事件与调用方法:服务合同 Service Contracts (6) 《WF编程》系列之27 &#8211; 基本活动:EventHandlingScopeActivity [...]]]></description>
			<content:encoded><![CDATA[<p>&nbsp;</p>
<p>最近一直在解决这样一个问题.<span id="more-738"></span></p>
<p>我的页面布局如下图:</p>
<p><img src="http://coding.windstyle.cn/files/cnblogs/o_TabContainer_AutoPostBack.png" alt="" width="612" height="433" /></p>
<p><span lang="zh-CN">其中</span><span lang="en-US">,TabPanel</span><span lang="zh-CN">是在Page_LoadComplete事件中动态创建的</span><span lang="en-US">,</span><span lang="zh-CN">采用此事件的原因是我想让用户先可以看到页面中的其它内容</span><span lang="en-US">.</span></p>
<p><span lang="en-US">TabContainer</span><span lang="zh-CN">的</span><span lang="en-US">AutoPostBack</span><span lang="zh-CN">设置为</span><span lang="en-US">True,</span><span lang="zh-CN">为每个</span><span lang="en-US">TabPanel</span><span lang="zh-CN">载入相应的内容</span><span lang="en-US">.</span></p>
<p><span lang="en-US">TabPanel</span><span lang="zh-CN">创建成功后</span><span lang="en-US">,</span><span lang="zh-CN">点击</span><span lang="en-US">TabPanel</span><span lang="zh-CN">的</span><span lang="en-US">Header</span><span lang="zh-CN">部分</span><span lang="en-US">,</span><span lang="zh-CN">就会弹出这样的错误</span><span lang="en-US">:</span></p>
<blockquote>
<p lang="en-US">Specified argument was out of the range of valid values.</p>
<p lang="en-US">Parameter name: index</p>
</blockquote>
<p><span lang="zh-CN">而且测试时发现</span><span lang="en-US">TabContainer</span><span lang="zh-CN">的</span><span lang="en-US">Client</span><span lang="zh-CN">与</span><span lang="en-US">Server</span><span lang="zh-CN">事件均没有被触发</span><span lang="en-US">.</span></p>
<p><span lang="zh-CN">又经过一番测试</span><span lang="en-US">,</span><span lang="zh-CN">终于发现</span><span lang="en-US">,</span><span lang="zh-CN">因为</span><span lang="en-US">PostBack</span><span lang="zh-CN">时触发的事件顺序是</span><span lang="en-US">:</span></p>
<blockquote>
<p><span style="font-family: Calibri" lang="en-US">Page_Init &gt; Page_Load &gt; </span><span style="font-family: 微软雅黑" lang="zh-CN">Page_LoadComplete</span><span style="font-family: Calibri" lang="en-US"> &gt; ControlEvent &gt; Page_Unload.</span></p>
</blockquote>
<p><span lang="zh-CN">由于我的</span><span lang="en-US">TabPanel</span><span lang="zh-CN">是在Page_LoadComplete事件中动态创建的</span><span lang="en-US">,</span><span lang="zh-CN">所以在所以</span><span lang="en-US">Page_Init</span><span lang="zh-CN">事件时</span><span lang="en-US">,</span><span lang="zh-CN">页面中根本就没有任何</span><span lang="en-US">TabPanel,</span><span lang="zh-CN">自然也就找不到对应的</span><span lang="en-US">index.</span></p>
<p><span lang="zh-CN">把动态创建</span><span lang="en-US">TabPanel</span><span lang="zh-CN">的方法写道</span><span lang="en-US">Page_Init</span><span lang="zh-CN">事件中就可以解决这个问题</span><span lang="en-US">.</span></p>

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://coding.windstyle.cn/2007/07/26/programming-wf-26-basic-activities-parallelactivity-amp-delayactivity-amp-listenactivity/" title="《WF编程》系列之26 &#8211; 基本活动:ParallelActivity &amp; DelayActivity &amp; ListenActivity (2007-07-26)">《WF编程》系列之26 &#8211; 基本活动:ParallelActivity &amp; DelayActivity &amp; ListenActivity</a> (8)</li>
	<li><a href="http://coding.windstyle.cn/2007/07/16/programming-wf-19-raise-events-and-invoke-method-implement-service-and-workflow/" title="《WF编程》系列之19 &#8211; 触发事件与调用方法:服务以及工作流的实现 (2007-07-16)">《WF编程》系列之19 &#8211; 触发事件与调用方法:服务以及工作流的实现</a> (10)</li>
	<li><a href="http://coding.windstyle.cn/2007/07/13/programming-wf-18-raise-events-and-invoke-methods-service-contracts/" title="《WF编程》系列之18 &#8211; 触发事件与调用方法:服务合同 Service Contracts (2007-07-13)">《WF编程》系列之18 &#8211; 触发事件与调用方法:服务合同 Service Contracts</a> (6)</li>
	<li><a href="http://coding.windstyle.cn/2007/07/26/programming-wf-27-basic-activitieseventhandlingscopeactivity-amp-synchronizationscopeactivity-amp-replicatoractivit/" title="《WF编程》系列之27 &#8211; 基本活动:EventHandlingScopeActivity &amp; SynchronizationScopeActivity &amp; ReplicatorActivity (2007-07-26)">《WF编程》系列之27 &#8211; 基本活动:EventHandlingScopeActivity &amp; SynchronizationScopeActivity &amp; ReplicatorActivity</a> (4)</li>
	<li><a href="http://coding.windstyle.cn/2007/04/28/programming-wf-16-external-world-of-workflow-life-cycle-event/" title="《WF编程》系列之16 &#8211; 工作流与外部世界:生存周期事件 (2007-04-28)">《WF编程》系列之16 &#8211; 工作流与外部世界:生存周期事件</a> (7)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://coding.windstyle.cn/2007/06/25/create-tabcontainer-dynamicly-and-set-autopostback/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ajax.net 1.0跨域访问错误的解决方法</title>
		<link>http://coding.windstyle.cn/2007/06/08/ajax-net-1-0-fix-cross-domain-acess-error/</link>
		<comments>http://coding.windstyle.cn/2007/06/08/ajax-net-1-0-fix-cross-domain-acess-error/#comments</comments>
		<pubDate>Fri, 08 Jun 2007 00:27:00 +0000</pubDate>
		<dc:creator>windie</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[ajax.net]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[跨域]]></category>

		<guid isPermaLink="false">http://776751</guid>
		<description><![CDATA[Ajax.net 1.0正式版发布已久,我在第一次尝试时却遇到跨域访问的问题,表现为在页面的任意位置单击鼠标左键都会弹出错误提示:&#8221;Access is denied&#8220;,搜索了一番,找到了解决方法. 1.将X:\Program Files\Microsoft ASP.NET\ASP.NET 2.0 AJAX Extensions\v1.0.61025\MicrosoftAjaxLibrary中的System.Web.Extensions文件夹复制到添加到项目中. 2.打开System.Web.Extensions\MicrosoftAjax.js文件,在其中找到case Sys.Browser.InternetExplorer节,将其内容替换为下面的代码: switch(Sys.Browser.agent){case Sys.Browser.InternetExplorer:Sys.UI.DomElement.getLocation=function(a){if(a.self&#124;&#124;a.nodeType===9)return new Sys.UI.Point(0,0);var b=a.getBoundingClientRect();if(!b)return new Sys.UI.Point(0,0);var c=a.document.documentElement,d=b.left-2+c.scrollLeft,e=b.top-2+c.scrollTop;try{var g=a.ownerDocument.parentWindow.frameElement&#124;&#124;null;if(g){var f=2-(g.frameBorder&#124;&#124;1)*2;d+=f;e+=f}}catch(h){}return new Sys.UI.Point(d,e)};break; 注意以上代码要写在一行中. 3.打开System.Web.Extensions\MicrosoftAjax.debug.js,在其中找到case Sys.Browser.InternetExplorer节,将其内容替换为下面的代码: Sys.UI.DomElement.getLocation = function(element) { &#160; &#160; if (element.self &#124;&#124; element.nodeType === 9) return new Sys.UI.Point(0,0); &#160; &#160; var clientRect = element.getBoundingClientRect(); &#160; &#160; if (!clientRect) { &#160; &#160; [...]]]></description>
			<content:encoded><![CDATA[<p style="margin: 0in;font-size: 10pt"><span style="font-family: Calibri" lang="en-US">Ajax.net 1.0</span><span style="font-family: 微软雅黑" lang="zh-CN">正式版发布已久</span><span style="font-family: Calibri" lang="en-US">,</span><span style="font-family: 微软雅黑" lang="zh-CN">我在第一次尝试时却遇到跨域访问的问题</span><span style="font-family: Calibri" lang="en-US">,</span><span style="font-family: 微软雅黑" lang="zh-CN">表现为在页面的任意位置单击鼠标左键都会弹出错误提示</span><span style="font-family: Calibri" lang="en-US">:&#8221;Access</span><span style="font-family: 微软雅黑" lang="en-US"> is denied</span><span style="font-family: Calibri" lang="en-US">&#8220;,</span><span style="font-family: 微软雅黑" lang="zh-CN">搜索了一番</span><span style="font-family: Calibri" lang="en-US">,</span><span style="font-family: 微软雅黑" lang="zh-CN">找到了解决方法</span><span style="font-family: Calibri" lang="en-US">.<span id="more-739"></span></span></p>
<p style="margin: 0in;font-size: 10pt"><span style="font-family: Calibri" lang="en-US">1.</span><span style="font-family: 微软雅黑" lang="zh-CN">将</span><span style="font-family: Calibri" lang="en-US">X</span><span style="font-family: 微软雅黑" lang="zh-CN">:\Program Files\Microsoft ASP.NET\ASP.NET 2.0 AJAX Extensions\v1.0.61025\MicrosoftAjaxLibrary中的System.Web.Extensions文件夹复制到添加到项目中</span><span style="font-family: Calibri" lang="en-US">.</span></p>
<p style="margin: 0in;font-size: 10pt"><span style="font-family: Calibri" lang="en-US">2.</span><span style="font-family: 微软雅黑" lang="zh-CN">打开System.Web.Extensions</span><span style="font-family: Calibri" lang="en-US">\MicrosoftAjax</span><span style="font-family: 微软雅黑" lang="en-US">.js</span><span style="font-family: 微软雅黑" lang="zh-CN">文件</span><span style="font-family: 微软雅黑" lang="en-US">,</span><span style="font-family: 微软雅黑" lang="zh-CN">在其中找到case Sys.Browser.InternetExplorer节</span><span style="font-family: 微软雅黑" lang="en-US">,</span><span style="font-family: 微软雅黑" lang="zh-CN">将其内容替换为下面的代码</span><span style="font-family: 微软雅黑" lang="en-US">:</span></p>
<p style="margin: 0in;font-size: 10pt"><span style="font-family: 微软雅黑" lang="zh-CN"></p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">switch(Sys.Browser.agent){case Sys.Browser.InternetExplorer:Sys.UI.DomElement.getLocation=function(a){if(a.self||a.nodeType===9)return new Sys.UI.Point(0,0);var b=a.getBoundingClientRect();if(!b)return new Sys.UI.Point(0,0);var c=a.document.documentElement,d=b.left-2+c.scrollLeft,e=b.top-2+c.scrollTop;try{var g=a.ownerDocument.parentWindow.frameElement||null;if(g){var f=2-(g.frameBorder||1)*2;d+=f;e+=f}}catch(h){}return new Sys.UI.Point(d,e)};break;</div></div>
<p>注意以上代码要写在一行中</span><span style="font-family: Calibri" lang="en-US">.</span></p>
<p style="margin: 0in;font-size: 10pt"><span style="font-family: Calibri" lang="en-US">3.</span><span style="font-family: 微软雅黑" lang="zh-CN">打开System.Web.Extensions</span><span style="font-family: Calibri" lang="en-US">\MicrosoftAjax</span><span style="font-family: 微软雅黑" lang="en-US">.</span><span style="font-family: 微软雅黑" lang="zh-CN">debug</span><span style="font-family: 微软雅黑" lang="en-US">.js,</span><span style="font-family: 微软雅黑" lang="zh-CN">在其中找到case Sys.Browser.InternetExplorer节</span><span style="font-family: 微软雅黑" lang="en-US">,</span><span style="font-family: 微软雅黑" lang="zh-CN">将其内容替换为下面的代码</span><span style="font-family: 微软雅黑" lang="en-US">:</span></p>
<p style="margin: 0in;font-size: 10pt">
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Sys.UI.DomElement.getLocation = function(element) {<br />
&nbsp; &nbsp; if (element.self || element.nodeType === 9) return new Sys.UI.Point(0,0);<br />
&nbsp; &nbsp; var clientRect = element.getBoundingClientRect();<br />
&nbsp; &nbsp; if (!clientRect) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; return new Sys.UI.Point(0,0);<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; var ownerDocument = element.document.documentElement;<br />
&nbsp; &nbsp; var offsetX = clientRect.left - 2 + ownerDocument.scrollLeft,<br />
&nbsp; &nbsp; &nbsp; &nbsp; offsetY = clientRect.top - 2 + ownerDocument.scrollTop;<br />
<br />
&nbsp; &nbsp; try {<br />
&nbsp; &nbsp; &nbsp; &nbsp; var f = element.ownerDocument.parentWindow.frameElement || null;<br />
&nbsp; &nbsp; &nbsp; &nbsp; if (f) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var offset = 2 - (f.frameBorder || 1) * 2;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; offsetX += offset;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; offsetY += offset;<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; catch(ex) {<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; return new Sys.UI.Point(offsetX, offsetY);<br />
}<br />
break;</div></div>
<p><span style="font-family: Calibri" lang="en-US">4.</span><span style="font-family: 微软雅黑" lang="zh-CN">为</span><span style="font-family: Calibri" lang="en-US">ScriptManager</span><span style="font-family: 微软雅黑" lang="zh-CN">添加</span><span style="font-family: Calibri" lang="en-US">ScriptReference,</span><span style="font-family: 微软雅黑" lang="zh-CN">引用到我们修改过的</span><span style="font-family: Calibri" lang="en-US">js</span><span style="font-family: 微软雅黑" lang="zh-CN">文件上</span><span style="font-family: 微软雅黑" lang="en-US">:</span></p>
<p style="margin: 0in;font-size: 10pt;font-family: 微软雅黑">
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;</div></div>
<p><span lang="zh-CN">参考文章</span><span lang="en-US">-1:</span><a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2007/04/13/kb-cross-domain-access-denied-issue-of-asp-net-ajax-page.aspx"><span lang="zh-CN">http://blog.darkthread.net/blogs/darkthreadtw/archive/2007/04/13/kb-cross-domain-access-denied-issue-of-asp-net-ajax-page.aspx</span></a></p>
<p style="margin: 0in;font-size: 10pt;font-family: 微软雅黑"><span lang="zh-CN">参考文章</span><span lang="en-US">-2:</span><a href="http://weblogs.asp.net/bleroy/archive/2007/01/31/how-to-work-around-the-quot-access-denied-quot-cross-domain-frame-issue-in-asp-net-ajax-1-0.aspx"><span lang="zh-CN">http://weblogs.asp.net/bleroy/archive/2007/01/31/how-to-work-around-the-quot-access-denied-quot-cross-domain-frame-issue-in-asp-net-ajax-1-0.aspx</span></a></p>

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://coding.windstyle.cn/2009/04/09/css-naked-day/" title="CSS裸奔日 (2009-04-09)">CSS裸奔日</a> (0)</li>
	<li><a href="http://coding.windstyle.cn/2008/03/28/fix-mouse-event-interference-of-html-inner-elements/" title="解决HTML内部元素的Mouse事件干扰 (2008-03-28)">解决HTML内部元素的Mouse事件干扰</a> (18)</li>
	<li><a href="http://coding.windstyle.cn/2007/07/12/3-layers-in-web/" title="Web中的三层 (2007-07-12)">Web中的三层</a> (0)</li>
	<li><a href="http://coding.windstyle.cn/2007/06/25/create-tabcontainer-dynamicly-and-set-autopostback/" title="动态创建的TabContainer及其AutoPostBack (2007-06-25)">动态创建的TabContainer及其AutoPostBack</a> (0)</li>
	<li><a href="http://coding.windstyle.cn/2008/04/29/build-fanfou-show-using-silverlight-2/" title="Silverlight 2 打造饭否Show (2008-04-29)">Silverlight 2 打造饭否Show</a> (31)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://coding.windstyle.cn/2007/06/08/ajax-net-1-0-fix-cross-domain-acess-error/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>简单倒计时与DateTime.Subtract()</title>
		<link>http://coding.windstyle.cn/2006/11/11/simple-countdown-and-datetime-subtract/</link>
		<comments>http://coding.windstyle.cn/2006/11/11/simple-countdown-and-datetime-subtract/#comments</comments>
		<pubDate>Sat, 11 Nov 2006 06:35:00 +0000</pubDate>
		<dc:creator>windie</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Subtract]]></category>
		<category><![CDATA[TimeSpan]]></category>
		<category><![CDATA[倒计时]]></category>

		<guid isPermaLink="false">http://coding.windstyle.cn/?p=260</guid>
		<description><![CDATA[软件工程的老师布置了一个任务,一个网络环境的 Turbo C 考试系统, 要求界面上有倒计时,由此. 拖放一个 Label 和一个 Timer 到主界面上,设置 Timer 的 Interval 为1000. 添加一个全局变量用以表示40分钟(考试时间)以后的时间点.&#160; private DateTime endTime; 在窗口载入事件中设置 endTime 的具体值并且启用 Timer.&#160; private void Form1_Load(object sender, EventArgs e) { &#160; &#160; &#160; endTime= DateTime.Now.AddMinutes(40); &#160; &#160; &#160; timer1.Enabled = true; } 在 Timer 的 Tick 事件中用 endTime 减去当前时间来获得剩余时间,籍此来实现倒计时.&#160; private void timer1_Tick(object sender, EventArgs e) { [...]]]></description>
			<content:encoded><![CDATA[<p>软件工程的老师布置了一个任务,一个网络环境的 Turbo C 考试系统, 要求界面上有倒计时,由此.</p>
<p><span id="more-260"></span></p>
<ol>
<li>拖放一个 Label 和一个 Timer 到主界面上,设置 Timer 的 Interval 为1000.</li>
<li>添加一个全局变量用以表示40分钟(考试时间)以后的时间点.&nbsp;
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">private DateTime endTime;</div></div>
</li>
<li>在窗口载入事件中设置 endTime 的具体值并且启用 Timer.&nbsp;
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">private void Form1_Load(object sender, EventArgs e)<br />
{<br />
&nbsp; &nbsp; &nbsp; endTime= DateTime.Now.AddMinutes(40);<br />
&nbsp; &nbsp; &nbsp; timer1.Enabled = true;<br />
}</div></div>
</li>
<li>在 Timer 的 Tick 事件中用 endTime 减去当前时间来获得剩余时间,籍此来实现倒计时.&nbsp;
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:500px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">private void timer1_Tick(object sender, EventArgs e)<br />
{<br />
&nbsp; &nbsp; &nbsp; DateTime show = start.Subtract(new TimeSpan(DateTime.Now.Ticks));<br />
&nbsp; &nbsp; &nbsp; label1.Text = show.ToLongTimeString();<br />
}</div></div>
</li>
</ol>
<p>注意这个方法: DateTime.Subtract() ,它有+1个重载:<br />
DateTime Subtract(TimeSpan) 和 TimeSpan Subtract(DateTime ) , 当参数为 DateTime 类型时,返回值为 TimeSpan 类型,当参数为 TimeSpan 时,返回值为 DateTime 类型.</p>

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li>No related posts.</li>
	</ul>

]]></content:encoded>
			<wfw:commentRss>http://coding.windstyle.cn/2006/11/11/simple-countdown-and-datetime-subtract/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
