When you have Silverlight application written in IronPython, it is a good idea to split it to several files so browser can cache them separately. Later, when you change something in your application, users will download only a small part. During my attemts with IronPython and Silverligt, I have found several catches. That's why I describe here my way how to distribute IronPython Silverlight application.
I distribute my application as one .html file, one
.xap file, and several .zip
files. I use .zip because IIS already knows what to do
with .zip files. The files are:
- index.html
- app.xap
- IronPython.zip - contains files from IronPython-2.6.1\Silverlight\bin:
IronPython.dll IronPython.Modules.dll
- Microsoft.Scripting.zip - contains files from IronPython-2.6.1\Silverlight\bin:
Microsoft.Dynamic.dll Microsoft.Scripting.dll Microsoft.Scripting.Core.dll Microsoft.Scripting.ExtensionAttribute.dll Microsoft.Scripting.Silverlight.dll
- SLToolkit.zip - contains files form Silverlight toolkit or SDK; in our case just
System.Windows.Controls.dll
Let's create a small application, that uses ChildWindow control from Silverlight toolkit:
C:\IronPython-2.6.1\Silverlight\script\sl.bat python childwindowChange the app.py and app.xml:
app.py
from System.Windows import Application from System.Windows.Controls import UserControl class App: def __init__(self): self.root = Application.Current.LoadRootVisual(UserControl(), "app.xaml") a = App()
app.xaml
<UserControl x:Class="System.Windows.Controls.UserControl" xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"> <controls:ChildWindow > <StackPanel> <TextBlock Text="Text in ChildWindow"/> <Button x:Name="btnNewWindow" Content="New window"/> </StackPanel> </controls:ChildWindow> </UserControl>
We don't want to Chiron automatically add necesary .dll files into .xap so we have to add our own AppManifest.xaml and languages.config into childwindow\app folder:
AppManifest.xaml
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" RuntimeVersion="2.0.31005.0" EntryPointAssembly="Microsoft.Scripting.Silverlight" EntryPointType="Microsoft.Scripting.Silverlight.DynamicApplication" ExternalCallersFromCrossDomain="ScriptableOnly"> <Deployment.Parts> </Deployment.Parts> <Deployment.ExternalParts> <ExtensionPart Source="Microsoft.Scripting.zip" /> <ExtensionPart Source="SLToolkit.zip" /> </Deployment.ExternalParts> </Deployment>
languages.config
<Languages> <Language names="IronPython,Python,py" languageContext="IronPython.Runtime.PythonContext" extensions=".py" assemblies="IronPython.dll;IronPython.Modules.dll" external="IronPython.zip"/> </Languages>
Now create all three .zip files and add them into childwindow folder.
To test the application with Chiron, run
C:\IronPython-2.6.1\Silverlight\bin\Chiron.exe /e: /d:childwindow
The /e: switch is important - it tells Chiron to not put any assembly into generated .xap file. Check the application on http://localhost:2060/index.html.
To generate .xap file for distribution, run:
C:\IronPython-2.6.1\Silverlight\bin\Chiron.exe /e: /d:childwindow\app /z:app.zap
If you want to use anything from external assemblies in the code, you have to add manually reference to those assemblies. For example, if you want to add a button that creates a new ChildWindow, you have to change you code like this:
app.py
from System.Windows import Application from System.Windows.Controls import UserControl class App: def __init__(self): self.root = Application.Current.LoadRootVisual(UserControl(), "app.xaml") self.root.btnNewWindow.Click += self.OnClick def OnClick(self, sender, event): import clr clr.AddReference('System.Windows.Controls') from System.Windows.Controls import ChildWindow self.root.panel.Children.Add(ChildWindow(Content='new window')) a = App()
app.xaml
<UserControl x:Class="System.Windows.Controls.UserControl" xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"> <controls:ChildWindow > <StackPanel x:Name="panel"> <TextBlock Text="Text in ChildWindow"/> <Button x:Name="btnNewWindow" Content="New window"/> </StackPanel> </controls:ChildWindow> </UserControl>
If you comment out the clr.AddReference line, ImportError appears. See the explanation in Jimmy's email.
You can download the example here but note the .zip files do not contain and .dlls.