[Silverlight] 動態呼叫並載入XAP 使用

2010/08/16

以前同事問我一個問題.. 是有關於Flex 中是不是可以動態把一顆swf給呼叫起來並且載入..
就突然想到.. 在Silverlight是否可以如法炮製.. 想不到其實原理是差不多的..

今天來筆記一下..如何做到動態呼叫XAP並且使用.. 案例說明..
首先有一個專案叫做BeCalled1 其中版面配置如下..
sshot-41

沒錯就是很簡單一個Image物件,一個TextBlock物件 …
XMAL Code 如下:


<UserControl x:Class="BeCalled1.MainPage"


xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"


xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">


 


<Grid x:Name="LayoutRoot" Background="Black" Width="320" Height="200">


<Image Height="177" Source="ashin.jpg" HorizontalAlignment="Left" Margin="12,12,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="204"   />


<TextBlock FontFamily="微軟正黑體" FontSize="14" Foreground="White" Height="23" HorizontalAlignment="Left" Margin="224,165,0,0" Name="textBlock1" Text="五月天-阿信" VerticalAlignment="Top"   />


</Grid>


</UserControl>





第二個被動態呼叫的專案叫做 BeCalled2

也是很簡單的一個XAP 只是多一個按鈕,把圖換一下讓兩個看起來有差異..

版面配置如下..

sshot-42



接下來就是要來介紹主要的專案了..

設計兩個按鈕分別 會載入 上面說的的兩個專案所產出的.Xap 檔 BeCalled1.xap 和 BeCalled2.xap

載入後會放入到cvsStage的Canvas中..



sshot-44



ps. 首先您得把 上述兩個專案所產出的.xap 檔 複製到執行專案下的ClientBin檔案夾下面..如下圖:

sshot-45



這邊只po上 Load BeCalled1.xap 的程式碼 …

按下 btnLoadXAP1 的 C# Code 如下:



private void btnLoadXAP1_Click(object sender, RoutedEventArgs e)


{


try


{


//下載BeCalled1.xap 


WebClient webClient = new WebClient();


webClient.OpenReadCompleted += webClient_OpenReadCompleted;


webClient.OpenReadAsync(new Uri("BeCalled1.xap", UriKind.RelativeOrAbsolute));


}


catch (Exception ex)


{


MessageBox.Show(ex.Message+","+ex.StackTrace);


}


}









完成後的事件處理 Code :



void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)


{


//判斷是否事件傳遞有錯誤如果有錯彈出警告視窗


if (e.Error != null)


{


MessageBox.Show("下載xap發生錯誤原因為 "+ e.Error);


return;


}


 


 


try


{


// 將XAP file 轉為stream 並將 BeCalled1.dll 取出


StreamResourceInfo sriDLL = Application.GetResourceStream(new StreamResourceInfo(e.Result as Stream, null), new Uri("BeCalled1.dll", UriKind.Relative));




if (sriDLL == null)


{




MessageBox.Show("無法將dll從xap(zip file)中取出");


return;


}


 


//進行反射(Reflection)


AssemblyPart assemblyPart = new AssemblyPart();


Assembly assembly = assemblyPart.Load(sriDLL.Stream);


 


if (assembly == null)


{


MessageBox.Show("無法反射成功!!");


}


 


 


//轉型成UserCOntrol


var uc = (UserControl)assembly.CreateInstance("BeCalled1.MainPage");


cvsStage.Children.Clear();


cvsStage.Children.Add(uc);


}


catch (Exception ex)


{


MessageBox.Show(ex.Message + ex.StackTrace);


}


 


 


}



ps. 1.呼叫時請注意 絕對路徑跟相對路徑問題,這邊都是採用相對路徑

     2.http://pagebrooks.com/archive/2009/05/17/a-smaller-xap-preloader-for-silverlight.aspx  這篇文章是把他包裝起來,寫得很棒。



這邊在此筆記一下…



範例:






讚一下:



範例下載:



BeCalled1:







BeCalled2 :





DynamicLoadXAPMemo:


0 意見:

程式 . 生活 . D小調.@2010 | Binary Design: One Winged Angel.