[Silverlight] 用 IronPython 創建和調用用戶控件

關於如何用動態語言跑 Silverlight 就不說了,可以參考代振軍的帖子。但是很多教程都沒有提到怎樣才能分模塊開發,在介紹完一個 app 後就結束了。現在來看一下如何實現用戶控件的動態加載,其實也很簡單。

關鍵是用到了 Application.LoadComponent 這個方法,他可以加載指定的 xaml,並轉換成某個類型的對象。爲了減少重複工作,我做了一個簡單的基類,叫做 UserControlBase. 整個例子的目錄結構如下:

/default.htm
/app
   app.xaml
   app.py
   usercontrol_base.py
   control1.xaml
   control1.py

其中 control1.xaml 和 control1.py 就類似於 C# 裏的 code behind 方式,不過這裏的關聯是要自己代碼裏來指定的。
例子的運行效果如下:

ipy_uc.png

點擊一下 “加載用戶控件”,子控件就會加載進來。而在子控件中也能獨立處理自己的事件。

下面是代碼:

app.xaml

<UserControl xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class
="System.Windows.Controls.UserControl" Width="400" Height="300">
    
<Grid x:Name="LayoutRoot" Background="White">
        
<StackPanel Orientation="Vertical">
            
<TextBlock>這是主頁面</TextBlock>
            
<Button x:Name="btnLoad" Content="加載用戶控件" />
            
<Border x:Name="placeHolder" Width="400" Height="300" Margin="0,20,0,0">
                
            
</Border>
        
</StackPanel>
    
</Grid>
</UserControl>

app.py

#coding: utf-8

from Microsoft.Scripting.Silverlight import DynamicApplication
from System.Windows.Controls import *
from System.Windows.Browser import *

class App:
    
def __init__(self):
        self.scene 
= DynamicApplication.Current.LoadRootVisual(UserControl(), "app.xaml")

    
def start(self):
        self.scene.btnLoad.Click 
+= self.btnLoad_Click

    
def btnLoad_Click(self, sender, eventArgs):
        
from control1 import Control1
        uc 
= Control1()
        self.scene.placeHolder.Child 
= uc.page

App().start()


usercontrol_base.py

#coding: utf-8

from Microsoft.Scripting.Silverlight import DynamicApplication
from System.Windows.Controls import *
from System.Windows.Browser import *

# 用戶控件基類
class UserControlBase:
    
def __init__(self):
        self.page 
= UserControl()
        
# 加載 Xaml
        DynamicApplication.Current.LoadComponent(self.page, self.get_xaml_path())
        
# 執行子類的初始化動作,可在子類中實現之。
        self.OnInit()

    
def OnInit(self):
        
pass


control1.xaml

<UserControl xmlns="http://schemas.microsoft.com/client/2007"
 xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
 x:Class
="System.Windows.Controls.UserControl" Width="400" Height="300">
    
<Grid x:Name="LayoutRoot" Background="#ccccff">
        
<StackPanel Orientation="Vertical">
            
<TextBlock x:Name="text1">這是子頁面</TextBlock>
            
<Button x:Name="button1" Content="test" />
        
</StackPanel>
    
</Grid>
</UserControl>


control1.py
#coding: utf-8

import System
from System.Windows import Application
from Microsoft.Scripting.Silverlight import DynamicApplication
from System.Windows.Controls import *
from System.Windows.Browser import *
from usercontrol_base import UserControlBase

class Control1(UserControlBase):
    
# 必須重寫該方法
    def get_xaml_path(self):
        
return "control1.xaml"
    
    
# 可自由決定是否重寫該方法
    def OnInit(self):
        self.page.button1.Click 
+= self.button1_Click

    
def button1_Click(self, sender, eventArgs):
        HtmlPage.Window.Alert(self.page.text1.Text)


這裏有一點值得注意,就是編寫的 xaml 文件中如果要包含中文,則最好保存爲 UTF-8 格式,否則文件加載時會報錯。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章