关于如何用动态语言跑 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 方式,不过这里的关联是要自己代码里来指定的。
例子的运行效果如下:
点击一下 “加载用户控件”,子控件就会加载进来。而在子控件中也能独立处理自己的事件。
下面是代码:
app.xaml
app.py
usercontrol_base.py
control1.xaml
control1.py
这里有一点值得注意,就是编写的 xaml 文件中如果要包含中文,则最好保存为 UTF-8 格式,否则文件加载时会报错。
关键是用到了 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 方式,不过这里的关联是要自己代码里来指定的。
例子的运行效果如下:

点击一下 “加载用户控件”,子控件就会加载进来。而在子控件中也能独立处理自己的事件。
下面是代码:
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 >
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()
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
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 >
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)
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 格式,否则文件加载时会报错。