[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 格式,否则文件加载时会报错。






原文地址:https://www.cnblogs.com/RChen/p/1258011.html