在我发现jQuery的HTML()与Load()的区别之后,我写一篇jQuery的HTML()与Load()的区别说明了这两个方法的特点和区别,之后我又发现了一个特别的情况,就是在Safari或IE8中不能执行脚本!

load()方法用ajax方式请求加载 的目标页面内容里含有javascript脚本时,并且还含有<head>标签时(对于一个完整的网页来说,这是很正常的),这时,页面中的 javascript脚本竟然无法顺利执行!去掉<head>标签,javascript脚本才能执行,在其实浏览器均无此情况发生,我实现 想不通这是为什么,还高手告之。

呵呵,有网友说看不懂,那是我表达的不清楚,那我就把我的测试代码放上来,大家看看结果:

测试一(成功!这个测试结果是能弹出警告框“hello world!...”):

1)主页面


<html>

<head>

<title></title>

<script src="js/jquery-1.4.4.min.js" type="text/javascript"></script>

<script type="text/javascript">

    $(document).ready(
function() {

        $(
"#target").load("target.html"function() {


        });

    });

</script>

</head>

<body>

<div id="target"></div>

</body>

</html>
2) 子页面
<script src="js/jquery-1.4.4.min.js" type="text/javascript"></script>

<script type="text/javascript">

    alert(
"hello world!I am target");

</script>

above is script

测试二(失败):

1)主页面:

 

<html>
<head>
<title></title>
<script src="js/jquery-1.4.4.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(
function() {
        $(
"#target").load("target1.html"function() {

        });
    });
</script>
</head>
<body>
<div id="target"></div>
</body>
</html>

2)子页面:

<html>
<head>
<script src="js/jquery-1.4.4.min.js" type="text/javascript"></script>
<script type="text/javascript">
    alert(
"hello world!I am target1");
</script>
</head>
<body>
above is script
</body>
</html>

 转自:

 
posted @ 2011-05-16 22:19 平常心成大事 阅读(164) 评论(0) 编辑

在ASP.NET Web service开发中,会用到一个很重要的类型:SoapException,它是一个基于Soap请求机制的异常处理类型, 这也是一个很重要的类型,在编写web service函数时,我们需要用它来抛出异常信息,以便供客户端获取并进行必要的异常处理. 我们可以在它的detail属性里加入自定义的详细的错误信息。

这里有两种写法,

第一种, 就是网上流转某大虾写的,用一个String变量任意拼构一个XML字符串,然后用XmlDocument load XML字符串,再将DocumentElement转入到SoapException中构造函数中:

       string strXmlOut = @"<detail>" //注意,一定要用小写的detail节点!
                         
+ "<Error>"
                         
+ "<ErrorNumber>" + errorNumber + "</ErrorNumber>"
                         
+ "<ErrorMessage>" + errorMessage + "</ErrorMessage>"
                         
+ "<ErrorSource>" + errorSource + "</ErrorSource>"
                         
+ "</Error>"
                         
+ "</detail>";

        
//装载为Xml文档
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(strXmlOut);

        
//实例化SoapException
        SoapException soapEx = new SoapException(errorMessage, faultCodeLocation, uri, xmlDoc.DocumentElement);

        throw soapEx;

 

第二种,就是MSDN里介绍的正规写法:

XmlDocument doc = new XmlDocument();
            XmlNode node = doc.CreateNode(XmlNodeType.Element,
                SoapException.DetailElementName.Name,
                SoapException.DetailElementName.Namespace);

 

XmlNode xmlErrorNumber= doc.CreateNode(XmlNodeType.Element, "ErrorNumber", "http://tempuri.org/");
            xmlErrorNumber
.InnerText = exceptionInfo.ErrorCode; //exceptionInfo是一个自定义类型 

            node.AppendChild(xmlErrorNumber);

XmlNode xmlErrorMessage= doc.CreateNode(XmlNodeType.Element, "ErrorMessage", "http://tempuri.org/");
            xmlErrorNumber
.InnerText = exceptionInfo.StackTrace; 

            node.AppendChild(xmlErrorMessage);  

            SoapException soapEx = new SoapException(exceptionInfo.ErrorMessage, faultCodeLocation, uri, node);

            throw soapEx; 

 

参考:http://www.techmango.com/blog/article/DotNet/ASP_NET_SoapExtension_SoapException.htm

posted @ 2010-11-24 21:35 平常心成大事 阅读(100) 评论(0) 编辑

不知道用Flex builder做开发的同伴们,是否有注意过Flex builder生成的flash的默认显示语言问题?如果你要开发的flex应用程序是全英文版的,但是你在安装Flex builder是中文版,那么flash的默认显示语言就是中文的了。其实我们可以在Flex builder里修改编译参数,这样默认显示的语言就正确了。具体地说, Flash player程序界面上默认显示的语言是在程序发布后就被设置好了,例如, 中文版本的flex builder开发出来的flash里的confirm弹出窗口上的按钮显示的就是中文, 即使你的操作系统设置语言的是English.如图:


 

 

Flex builder里更改flash的Globalization的方法如下:

 

在FLEX项目中

右键—>Properties—>Flex Compiler
在Additional compiler arguments选项下面的输入框, 如中文版的flash环境就是-locale zh_HK ,要想将显示语言改成英文显示,就将最后面的zh_HK改成en_US.最后的效果如下图:

http://www.techmango.com/blog/article/FlexTech/Flex_builder_Change_Globalization_Of_Flash.htm

 

posted @ 2010-11-24 21:14 平常心成大事 阅读(266) 评论(0) 编辑

用Flex/Flash做开发的同志们应该会使用 expandChildrenOf(item,true)方法来使用Tree组件在绑定数据后自动展开所有树型节点(不需要用户再自己点击展开节点,会方 便许多),而在Flex开发帮忙文档中很明确写道:

"If you set dataProvider and then immediately call expandChildrenOf() you may not see the correct behavior. You should either wait for the component to validate or call the validateNow() method. "

如果使用不当,是看不到任何效果的,这会让许多新手郁闷不以!

  我发现网上流传下面两种代码: 

 

Tree的全部节点展开 - royanxin  - royanxin的博客第一种:

treePlayList.dataProvider=results;//刷新Tree的全部节点展开 -  royanxin - royanxin的博客

treePlayList.validateNow();//全部展开

treePlayList.selectedIndex=0;

treePlayList.expandChildrenOf(treePlayList.selectedItem,true);

但有些人试过不行, 我也不知道为什么。

第二种:

某些稍微聪明一点的人受到 启发想用个延时后再执行就行了:

setTimeout(IniExpand, 1000); //延时1秒

private function IniExpand():void {
              TreeView1.selectedIndex=1;
              TreeView1.expandItem(TreeView1.selectedItem,true);
            }

不过,我亲自试了,根本无 效嘛~


其实,我自己想到了一个我 认为是权威准确的方法,那就是用callLater方法,再加上匿名代理方法!!!

代码如 下:

myTree.callLater(

    function ():void{myTree.expandChildrenOf(selectedItem.root[0],true);}

  ); //selectedItem.root当然起始节点了(这是在 flash builder 4中测试成功)

这个方法是在某天开窍突然 想到Flex/Flash会像C#语言那样,能在方法的参数体里定义一个匿名方法呢?, 类似C#里的匿名代理方法delegate, 结果一试果然成功了,呵呵.

 

转自:http://www.techmango.com/blog/article/FlexTech/Flex_Tree_Auto_expandChildrenOf.htm

 

posted @ 2010-06-24 16:13 平常心成大事 阅读(1209) 评论(0) 编辑

使用C#进行多线程编程经常会用队列池进行线程同步的方法,实现就用到Queue。Queue是线程安全的(Thread safe),但不是泛型的,对象出列时需要进行拆箱转换。也有人会马上想到Queue<T>,但可惜的是泛型Queue<T>却不是线程安全,我们需要用其它编程方法来实现它。

下面介绍一种方法,它能够使用泛型Queue<T>进行线程同步,但是需要用到 lock 关键字以及 AutoResetEvent ManualResetEvent 类对主线程和两个辅助线程进行线程同步。


该示例创建两个辅助线程。一个线程生成元素并将它们存储在非线程安全的泛型队列中。另一个线程使用此队列中的项。另外,主线程定期显示队列的内容,以便该队列可由三个线程进行访问。lock 关键字用于同步对队列的访问,以确保队列的状态不会被破坏。

除了只是使用 lock 关键字来防止同时访问以外,还可以用两个事件对象提供进一步的同步。一个事件对象用来通知辅助线程终止,另一个事件对象由制造者线程用来在有新项添加到队列中时通知使用者线程。这两个事件对象封装在一个名为 SyncEvents 的类中。这使事件可以轻松传递给表示制造者线程和使用者线程的对象。SyncEvents 类按如下方式定义:

C#
public class SyncEvents
{
public SyncEvents()
{

_newItemEvent = new AutoResetEvent(false);
_exitThreadEvent = new ManualResetEvent(false);
_eventArray = new WaitHandle[2];
_eventArray[0] = _newItemEvent;
_eventArray[1] = _exitThreadEvent;
}

public EventWaitHandle ExitThreadEvent
{
get { return _exitThreadEvent; }
}
public EventWaitHandle NewItemEvent
{
get { return _newItemEvent; }
}
public WaitHandle[] EventArray
{
get { return _eventArray; }
}

private EventWaitHandle _newItemEvent;
private EventWaitHandle _exitThreadEvent;
private WaitHandle[] _eventArray;
}

对“新项”事件使用 AutoResetEvent 类,因为您希望每当使用者线程响应此事件后,此事件都能自动重置。或者,将 ManualResetEvent 类用于“退出”事件,因为您希望当此事件终止时有多个线程响应。如果您改为使用 AutoResetEvent,则仅在一个线程响应该事件以后,该事件就还原到非终止状态。另一个线程不会响应,因此在这种情况下,将无法终止。

SyncEvents 类创建两个事件,并将它们以两种不同的形式存储:一种是作为 EventWaitHandle(它是 AutoResetEventManualResetEvent 的基类),一种是作为基于 WaitHandle 的数组。如关于使用者线程的讨论中所述,此数组是必需的,因为它使使用者线程可以响应两个事件中的任何一个。

使用者线程和制造者线程分别由名为 Consumer 和 Producer 的类表示。这两个类都定义了一个名为 ThreadRun 的方法。这些方法用作 Main 方法创建的辅助线程的入口点。

Producer 类定义的 ThreadRun 方法如下所示:

C#
// Producer.ThreadRun
public void ThreadRun()
{
int count = 0;
Random r = new Random();
while (!_syncEvents.ExitThreadEvent.WaitOne(0, false))
{
lock (((ICollection)_queue).SyncRoot)
{
while (_queue.Count < 20)
{
_queue.Enqueue(r.Next(0,100));
_syncEvents.NewItemEvent.Set();
count++;
}
}
}
Console.WriteLine("Producer thread: produced {0} items", count);
}

此方法一直循环,直到“退出线程”事件变为终止状态。此事件的状态由 WaitOne 方法使用 SyncEvents 类定义的 ExitThreadEvent 属性进行测试。在这种情况下,检查该事件的状态不会阻止当前线程,因为 WaitOne 使用的第一个参数为零,这表示该方法应立即返回。如果 WaitOne 返回 true,则说明该事件当前处于终止状态。如果是这样,ThreadRun 方法将返回,其效果相当于终止执行此方法的辅助线程。

在“退出线程”事件终止前,Producer.ThreadStart 方法将尝试在队列中保留 20 项。项只是 0 到 100 之间的一个整数。在添加新项前,必须锁定该集合,以防止使用者线程和主线程同时访问该集合。这一点是使用 lock 关键字完成的。传递给 lock 的参数是通过 ICollection 接口公开的 SyncRoot 字段。此字段专门为同步线程访问而提供。对该集合的独占访问权限被授予 lock 后面的代码块中包含的所有指令。对于制造者添加到队列中的每个新项,都将调用“新项”事件的 Set 方法。这将通知使用者线程离开挂起状态并开始处理新项。

Consumer 对象还定义名为 ThreadRun 的方法。与制造者的 ThreadRun 类似,此方法由 Main 方法创建的辅助线程执行。然而,使用者的 ThreadStart 必须响应两个事件。Consumer.ThreadRun 方法如下所示:

C#
// Consumer.ThreadRun
public void ThreadRun()
{
int count = 0;
while (WaitHandle.WaitAny(_syncEvents.EventArray) != 1)
{
lock (((ICollection)_queue).SyncRoot)
{
int item = _queue.Dequeue();
}
count++;
}
Console.WriteLine("Consumer Thread: consumed {0} items", count);
}

此方法使用 WaitAny 来阻止使用者线程,直到所提供的数组中的任意一个等待句柄变为终止状态。在这种情况下,数组中有两个句柄,一个用来终止辅助线程,另一个用来指示有新项添加到集合中。WaitAny 返回变为终止状态的事件的索引。“新项”事件是数组中的第一个事件,因此索引零表示新项。在这种情况下,检查索引 1(它指示“退出线程”事件),并使用它来确定此方法是否继续使用项。如果“新项”事件处于终止状态,您将通过 lock 获得对集合的独占访问权限并使用新项。因为此示例生成并使用数千个项,所以不显示使用的每个项,而是使用 Main 定期显示队列中的内容,如下面所演示的那样。

Main 方法首先创建一个队列(该队列的内容将被生成和使用)和 SyncEvents 的一个实例(已在前面演示):

C#
Queue<int> queue = new Queue<int>();
SyncEvents syncEvents = new SyncEvents();

然后,Main 配置 Producer 和 Consumer 对象以供辅助线程使用。然而,此步骤并不创建或启动实际的辅助线程:

C#
Producer producer = new Producer(queue, syncEvents);
Consumer consumer = new Consumer(queue, syncEvents);
Thread producerThread = new Thread(producer.ThreadRun);
Thread consumerThread = new Thread(consumer.ThreadRun);

请注意,队列和同步事件对象作为构造函数参数同时传递给 Consumer 和 Producer 线程。这提供了两个对象,它们具有执行各自任务所需的共享资源。然后创建两个新的 Thread 对象,并使用每个对象的 ThreadRun 方法作为参数。每个辅助线程在启动时都将此参数用作线程的入口点。

接着,Main 通过调用 Start 方法来启动两个辅助线程,如下所示:

C#
producerThread.Start();
consumerThread.Start();

此时,创建了两个新的辅助线程,它们独立于当前正在执行 Main 方法的主线程开始异步执行过程。事实上,Main 接下来要做的事情是通过调用 Sleep 方法将主线程挂起。该方法将当前正在执行的线程挂起指定的时间(毫秒)。在此时间间隔过后,Main 将重新激活,这时它将显示队列的内容。Main 重复此过程四次,如下所示:

C#
for (int i=0; i<4; i++)
{
Thread.Sleep(2500);
ShowQueueContents(queue);
}

最后,Main 通过调用“退出线程”事件的 Set 方法通知辅助线程终止,然后对每个辅助线程调用 Join 方法以阻止主线程,直到每个辅助线程都响应该事件并终止。

有一个线程同步的最终示例:ShowQueueContents 方法。与制造者线程和使用者线程类似,此方法使用 lock 获得对队列的独占访问权限。然而在这种情况下,独占访问非常重要,因为 ShowQueueContents 对整个集合进行枚举。对集合进行枚举是一个特别容易由于异步操作而造成数据损坏的操作,因为它需要遍历整个集合的内容。

请注意,ShowQueueContents 是由主线程执行的,因为它被 Main 调用。这意味着,当此方法获得对项队列的独占访问权限时,既阻止了制造者线程访问队列,也阻止了使用者线程访问队列。ShowQueueContents 锁定队列并枚举其内容:

C#
private static void ShowQueueContents(Queue<int> q)
{
lock (((ICollection)q).SyncRoot)
{
foreach (int item in q)
{
Console.Write("{0} ", item);
}
}
Console.WriteLine();
}
http://www.techmango.com/blog/article/DotNet/Multple_thread_Generic_Queue_synchronization.htm
posted @ 2009-10-23 16:10 平常心成大事 阅读(949) 评论(0) 编辑
在简单游戏的开发中实现视线追逐,有经典的算法:Bresenham算法。
Bresenham算法的原理是,计算每一点与终点之间的的横轴与纵轴,然后比较两轴的长度,哪个轴比较长,就往该方向前进,如果两轴等长,则往斜边前进。
C++实现代码如下:
Code
posted @ 2009-09-13 13:49 平常心成大事 阅读(135) 评论(0) 编辑

转自:http://www.techmango.com/blog/article/DotNet/Csharp_WinForm_WebServices_AutoUpdate.htm

相信有许多程序员都喜欢用Winform做开发吧?!因为Winform相对Webform而言,优点是,功能更强大,编程更方便.但是它的缺点,就是软件的安装及维护是相当麻烦地,要实现软件更新,需要到客户端一台一台地升级。

本文就是介绍如何在C#中用Webservice为Winform实现自动升级的功能。

一、自动升级的技术原理
升级的原理有好几个,首先无非是将现有版本与最新版本作比较,发现最新的则提示用户是否升级。当然也有人用其它属性比较的,例如:文件大小。:) 或者更新日期。

二、实现技术细节
实现的技术有许多种,许多高手都知道了,但是在这里,我们要介绍的是用最新的基于Microsoft .Net的WebServices技术来实现Winform的自动升级功能(当然我们还可以用WebRequest, .NET是简单易用强大的滴:))。

实现原理:在WebServices中实现一个GetVer的WebMethod方法,其作用是获取当前的最新版本。然后将现在版本与最新版本比较,如果有新版本,则进行升级。

步骤:

1、准备一个XML文件 (Update.xml)。
<?xml version="1.0" encoding="utf-8" ?>
<product>
<version>1.0.1818.42821</version>
<description>修正一些Bug</description>
<filelist count="4" sourcepath="./update/">
<item name="City.xml" size="">
<value />
</item>
<item name="CustomerApplication.exe" size="">
<value />
</item>
<item name="Interop.SHDocVw.dll" size="">
<value />
</item>
<item name="Citys.xml" size="">
<value />
</item>
</filelist>
</product>
作用是作为一个升级用的模板。

2、WebServices的GetVer方法。

[WebMethod(Description="取得更新版本")]
public string GetVer()
{
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("update.xml"));
XmlElement root = doc.DocumentElement;
return root.SelectSingleNode("version").InnerText;
}

3、WebServices的GetUpdateData方法。
[WebMethod(Description="在线更新软件")]
[SoapHeader("sHeader")]
public System.Xml.XmlDocument GetUpdateData()
{
//验证用户是否登陆
if(sHeader==null)
return null;
if(!DataProvider.GetInstance.CheckLogin(sHeader.Username,sHeader.Password))
return null;
//取得更新的xml模板内容
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("update.xml"));
XmlElement root = doc.DocumentElement;
//看看有几个文件需要更新
XmlNode updateNode = root.SelectSingleNode("filelist");
string path = updateNode.Attributes["sourcepath"].Value;
int count = int.Parse(updateNode.Attributes["count"].Value);
//将xml中的value用实际内容替换
for(int i=0;i<count;i++)
{
XmlNode itemNode = updateNode.ChildNodes[i];
string fileName = path + itemNode.Attributes["name"].Value;
FileStream fs = File.OpenRead(Server.MapPath(fileName));
itemNode.Attributes["size"].Value = fs.Length.ToString();
BinaryReader br = new BinaryReader(fs);
//这里是文件的实际内容,使用了Base64String编码
itemNode.SelectSingleNode("value").InnerText = Convert.ToBase64String(br.ReadBytes((int)fs.Length),0,(int)fs.Length);
br.Close();
fs.Close();
}
return doc;
}

4、在客户端进行的工作。
首先引用此WebServices,例如命名为:WebSvs,
string nVer = Start.GetService.GetVer(); 
if(Application.ProductVersion.CompareTo(nVer)<=0)
update();

在本代码中 Start.GetService是WebSvs的一个Static 实例。首先检查版本,将结果与当前版本进行比较,如果为新版本则执行Update方法。
void update()
{
this.statusBarPanel1.Text = "正在下载...";
System.Xml.XmlDocument doc = ((System.Xml.XmlDocument)Start.GetService.GetUpdateData());
doc.Save(Application.StartupPath + @"\update.xml");
System.Diagnostics.Process.Start(Application.StartupPath + @"\update.exe");
Close();
Application.Exit();
}

这里为了简单起见,没有使用异步方法,当然使用异步方法能更好的提高客户端体验, 这个需要读者们自己去添加。:) update的作用是将升级的XML文件下载下来,保存为执行文件目录下的一个Update.xml文件。任务完成,退出程序,等待Update.Exe 来进行升级。   

5、Update.Exe 的内容。

private void Form1_Load(object sender, System.EventArgs e)
{
System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcesses();
foreach(System.Diagnostics.Process p in ps)
{
//MessageBox.Show(p.ProcessName);
if(p.ProcessName.ToLower()=="customerapplication")
{
p.Kill();
break;
}
}
XmlDocument doc = new XmlDocument();
doc.Load(Application.StartupPath + @"\update.xml");
XmlElement root = doc.DocumentElement;
XmlNode updateNode = root.SelectSingleNode("filelist");
string path = updateNode.Attributes["sourcepath"].Value;
int count = int.Parse(updateNode.Attributes["count"].Value);
for(int i=0;i<count;i++)
{
XmlNode itemNode = updateNode.ChildNodes[i];
string fileName = itemNode.Attributes["name"].Value;
FileInfo fi = new FileInfo(fileName);
fi.Delete();
//File.Delete(Application.StartupPath + @"\" + fileName);
this.label1.Text = "正在更新: " + fileName + " (" + itemNode.Attributes["size"].Value + ") ...";
FileStream fs = File.Open(fileName,FileMode.Create,FileAccess.Write);
fs.Write(System.Convert.FromBase64String(itemNode.SelectSingleNode("value").InnerText),0,int.Parse(itemNode.Attributes["size"].Value));
fs.Close();
}
label1.Text = "更新完成";
File.Delete(Application.StartupPath + @"\update.xml");
label1.Text = "正在重新启动应用程序...";
System.Diagnostics.Process.Start("CustomerApplication.exe");
Close();
Application.Exit();
}

这段代码的主要意思是,首先就是找到主进程,如果没有关闭,则用 Process.Kill()来关闭主程序。然后则用一个XmlDocument来Load程序生成的update.xml文件。用xml文件里指定的路 径和文件名来生成指定的文件,在这之前先前已经存在的文件删除。更新完毕后,则重新启动主应用程序。这样更新就完成了。

posted @ 2009-09-13 13:29 平常心成大事 阅读(228) 评论(0) 编辑
摘要: 有时候需要在DataGrid(GridView)里显示的数据列数是不固定的,而且还需要对数列列进行控制,如显示或隐藏,这时我们就不能用DataGrid里的自动生成列,更不能对列做数据绑定了,但我们有个办法,就是动态地生成数据列,DataGrid的动态列其实就是以类的形式存在,功能很强大.要实现动态列,首先要添加一个类文件,这个类必须要继承ITemplate接口,主要是要实现一个方法:Instant...阅读全文
posted @ 2008-04-23 20:58 平常心成大事 阅读(1231) 评论(0) 编辑
摘要: 众所周知,很多网站做个浮动广告条,都需要做个浮动层,用DW会帮你做好,生成这样的样式:#Layer1 {position:absolute;width:200px;height:115px;z-index:1;}之后再调浮动层跟踪滚动条的JS特效(本人用的简单方法:onscroll实现随滚动条浮动的层)可是用这个JS特效之后,感觉效果还是不理想,拉动滚动条大幅度移动时, 浮动层跟滚动条跑来跑去. ...阅读全文
posted @ 2008-04-21 22:42 平常心成大事 阅读(5192) 评论(1) 编辑
摘要: 曾经流行一时的HTML标记语言已经被官方认为过时了,将要接任它的是XHTML(http://www.w3.org/MarkUp/)。如果你的网站按照较严格的XHTML规则书写,那么这个网站将在不同的浏览器中保持一致的样式。并且你可以认为在未来浏览器的版本升级变化中仍然保证网站外观的一致性。同样你也会得到跨浏览器,跨设备以及跨平台的一致性支持。XHTML有如下两个主要目标: 将文档的结构(使用XHT...阅读全文
posted @ 2008-04-17 22:39 平常心成大事 阅读(1269) 评论(0) 编辑