WPF/Silverlight深度解决方案:(十六)传值实现
許多開(kāi)發(fā)者在從.NET網(wǎng)站開(kāi)發(fā)向Silverlight轉(zhuǎn)型過(guò)程中往往都會(huì)經(jīng)歷一個(gè)比較郁悶的過(guò)度期:Silverlight作為鑲嵌在網(wǎng)頁(yè)中的插件,如何能像傳統(tǒng)ASP.NET網(wǎng)頁(yè)一樣實(shí)現(xiàn)頁(yè)面切換及參數(shù)傳遞等問(wèn)題時(shí)常捆饒著大家。解決之道我們還得從本質(zhì)談起。
ASP.NET網(wǎng)站主要是基于服務(wù)器端的開(kāi)發(fā)(runat="server");由于在服務(wù)器中運(yùn)行,因此ASPX動(dòng)態(tài)頁(yè)面操作的都是服務(wù)器端對(duì)象,比如訪問(wèn)服務(wù)器中的數(shù)據(jù)庫(kù)等;而Silverlight則是標(biāo)準(zhǔn)的客戶端插件(<object …),如果去掉它的網(wǎng)頁(yè)外殼(out-of-browser),它的形態(tài)與客戶端軟件幾乎無(wú)差別,在安全使用范圍內(nèi)它能與用戶的電腦直接進(jìn)行數(shù)據(jù)交互;相反,如果想通過(guò)Silverlight去訪問(wèn)網(wǎng)絡(luò)上某臺(tái)服務(wù)器中的數(shù)據(jù)庫(kù),則必須勞駕第三者如WCF等作為傳輸中介。
因此,對(duì)于初學(xué)Silverlight的朋友我強(qiáng)烈建議大家深刻分清楚 服務(wù)器端 與 客戶端 的區(qū)別,就像當(dāng)初在學(xué)習(xí)ASP.NET時(shí),必須分清服務(wù)器端控件與客戶端控件的區(qū)別一樣。
大家先看個(gè)例子:我們創(chuàng)建一個(gè)Silverlight應(yīng)用程序網(wǎng)站,此時(shí)整個(gè)解決方案中將包含兩個(gè)項(xiàng)目分別為Silverlight項(xiàng)目和Web網(wǎng)站項(xiàng)目,為了進(jìn)行對(duì)比分析,我們?cè)?/span>Web網(wǎng)站項(xiàng)目中添加一個(gè)ASP.NET頁(yè)面,然后分別在該兩個(gè)項(xiàng)目中均編寫(xiě)代碼一模一樣的靜態(tài)類(lèi)Global.cs:
??? public static class Global {
??????? public static int num = 50;
}
接著在Index.aspx頁(yè)面中添加一個(gè)按鈕,每次點(diǎn)擊時(shí)num值增加50:
Index.aspx:
??? <div>
??????? <asp:Button ID="button1" Text="確定" runat="server" OnClick="button1_OnClick" />
??????? <asp:TextBox ID="textBox1" runat="server" />
??? </div>
Index.aspx.cs:
??????? protected void button1_OnClick(object sender, EventArgs e) {
??????????? Global.num += 50;
??????????? textBox1.Text = Global.num.ToString();
??????? }
同樣在MainPage.xaml中添加一個(gè)按鈕,每次點(diǎn)擊時(shí)num值也增加50:
MainPage.xaml:
??? <Canvas>
??????? <Button x:Name="button1" Content="確定" Click="button1_Click"/>
??????? <TextBox x:Name="textBox1" Canvas.Left="30" Width="85" />
??? </Canvas>
MainPage.xaml.cs
??????? private void Button1_Click(object sender, RoutedEventArgs e) {
??????????? Global.num += 50;
??????????? textBox1.Text = Global.num.ToString();
??????? }
嘗試一:用戶A訪問(wèn)Index.aspx頁(yè)面,點(diǎn)擊1次button1按鈕;接下來(lái)用戶B也訪問(wèn)該頁(yè)面,同樣也點(diǎn)擊1次該按鈕;此時(shí)用戶B電腦中顯示的num值是多少?如果用戶A接下來(lái)又點(diǎn)擊了1次該按鈕,用戶A電腦中的textBox1最終顯示的num值是多少?
嘗試二:用戶A訪問(wèn)Index.aspx頁(yè)面,點(diǎn)擊1次該頁(yè)面Silverlight程序MainPage中的button1按鈕;接下來(lái)用戶B也訪問(wèn)該頁(yè)面的Silverlight程序,并點(diǎn)擊MainPage中的該按鈕1次,此時(shí)用戶B電腦中顯示的num值是多少?如果用戶A之后又點(diǎn)擊了1次該按鈕,用戶A電腦中的textBox1最終顯示的num值是多少?
這是非常深刻而有意義的例子,答案是什么?大家不妨自己練習(xí)一次。
到此,如果大家能充分理解服務(wù)器端與客戶端的區(qū)別,那么Silverlight中的傳值就相當(dāng)好理解了。
在ASP.NET網(wǎng)站開(kāi)發(fā)中,由Index1.aspx跳轉(zhuǎn)到Index2.aspx并傳遞ID和PWD參數(shù),我們可以在Index1.aspx中通過(guò)Response.Redirect("Index2.aspx?ID={0}&PWD={1}",p1,p2);或Server.Transfer("Index2.aspx……");等方式進(jìn)行操作。而在Silverlight應(yīng)用程序中,由MainPage1.xaml向MainPage2.xaml切換則必須通過(guò)一個(gè)包含它們的第三者中介容器器類(lèi)控件比如Canvas或Grid等。因?yàn)殡m然它們名字中都有個(gè)Page,但確切講它們并不是頁(yè)面,而本質(zhì)是用戶控件;因此從一個(gè)控件向另一個(gè)控件傳值必須通過(guò)屬性或構(gòu)造函數(shù)進(jìn)行傳遞,且過(guò)程中還得移除掉MainPage1后再添加MainPage2。
按照以上思路,我們首先在MainPage2.xaml.cs中定義好參數(shù)的屬性或則構(gòu)造函數(shù)參數(shù),例如:
??????? public long ID { get; set; }
??????? public string PWD { get; set; }
或者:
??????? public MainPage2(long id, string pwd) {
??????????? InitializeComponent();
??????? }
當(dāng)需要由MainPage1向MainPage2切換時(shí),在Canvas或Grid中我們先移除掉MainPage1實(shí)例:
LayoutRoot.Children.Remove(mainPage1);
然后攜帶參數(shù)創(chuàng)建MainPage2的實(shí)例:
???? MainPage2 mainPage2 = new MainPage2() {
???????? ID = p1,
???????? PWD = p2,
???????? ...
???? };
或者:
MainPage2 mainPage2 = new MainPage2(p1, p2,…);
?? 最后將mainPage2添加進(jìn)LayoutRoot:
LayoutRoot.Children.add(mainPage2);
?? 到此大家也應(yīng)該感受到,如果您是初學(xué)Silverlight,并且假如您的大腦中里已經(jīng)駐扎了較深刻的ASP.NET網(wǎng)站開(kāi)發(fā)的知識(shí)經(jīng)驗(yàn),那么您必須進(jìn)行思維的轉(zhuǎn)變才能更快的融入到Silverlight的開(kāi)發(fā)中。
接下來(lái)我們不妨再往更深層次的方向探索,MainPage的本質(zhì)是繼承自UserControl的用戶控件(MainPage : UserControl),那么用戶控件的本質(zhì)又是什么呢?其實(shí)不就是類(lèi)(Class)嗎。因此,Silverlight中傳值的本質(zhì)就是類(lèi)與類(lèi)之間的屬性值傳遞,此時(shí)我們可以嘗試將項(xiàng)目中所有的用戶控件都刪除掉,然后添加同樣名字的類(lèi)進(jìn)去,讓它們分別也繼承自UserControl,最后的執(zhí)行效果一模一樣,大家是否已經(jīng)領(lǐng)悟到什么了?
?? 沒(méi)錯(cuò),在傳統(tǒng)的ASP.NET網(wǎng)站開(kāi)發(fā)中,我們是如何創(chuàng)建一個(gè)帶參數(shù)的類(lèi)的實(shí)例的,那么在Silverlight中的做法也一模一樣;僅有的一點(diǎn)區(qū)別是Silverlight中繼承自UserControl的類(lèi)擁有一個(gè)UI外殼,很形象的為它們冠以Page的名稱描述目的是讓開(kāi)發(fā)者從ASP.NET網(wǎng)站開(kāi)發(fā)向Silverlight轉(zhuǎn)型時(shí)更加親切,我們從VisualStudio新建Silverlight應(yīng)用程序模板中得到證實(shí)。
最后再回到本文的開(kāi)頭,我們通過(guò)兩種嘗試體驗(yàn)了靜態(tài)變量在服務(wù)器端與客戶端的不同表現(xiàn),結(jié)果也在意料之中,.NET網(wǎng)站中靜態(tài)變量存儲(chǔ)于服務(wù)器的內(nèi)存中,因此所有用戶看到且操作的都是同一個(gè)變量對(duì)象。而Silverlight應(yīng)用程序中的靜態(tài)變量則存儲(chǔ)于用戶各自的電腦內(nèi)存中,也就是說(shuō)每個(gè)用戶操作的都是自己電腦中的對(duì)象,這樣的特性我們是否也可以將之作為Silverlight傳值的媒介呢?
處理時(shí)只需Global.args = value;對(duì)該全局靜態(tài)變量進(jìn)行賦值,然后不論切換到哪個(gè)控件,該控件需要參數(shù)時(shí)直接取用即可。歸納一下:Silverlight中的靜態(tài)變量在程序的啟動(dòng)之初就駐扎用戶電腦內(nèi)存,不存在多用戶并發(fā),不僅方便,高效,自由;而且無(wú)須考慮控件的生命周期,實(shí)乃Silverlight項(xiàng)目開(kāi)發(fā)的萬(wàn)用利器。
小結(jié):傳值僅僅是我們平常開(kāi)發(fā)中會(huì)遇到的最常見(jiàn)問(wèn)題之一,本文通過(guò)ASP.NET網(wǎng)頁(yè)與Silverlight控件的分析對(duì)比,目的旨在告訴大家Silverlight運(yùn)行于客戶端上,這句話不僅僅是一個(gè)定義,而且還深刻蘊(yùn)涵著Silverlight的原理以及運(yùn)行機(jī)制,知其然且知其所以然在開(kāi)發(fā)中解決各種問(wèn)題才能更顯游刃有余。
作者:深藍(lán)色右手
出處:http://alamiye010.cnblogs.com/
本系列目錄及源碼下載:點(diǎn)擊進(jìn)入(歡迎加入WPF/Silverlight小組 WPF/Silverlight博客團(tuán)隊(duì))
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載。但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面顯著位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。
轉(zhuǎn)載于:https://www.cnblogs.com/alamiye010/archive/2010/06/17/1759611.html
總結(jié)
以上是生活随笔為你收集整理的WPF/Silverlight深度解决方案:(十六)传值实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一款学习机最多可以添加多少个孩子的名字
- 下一篇: 作品[RFileRead/WriteSt