Silverlight hosting in WINFORM application
Introduction: Silverlight and windows based applications are totally different things. These not only run in separate processes but they are different in the nature also. Windows application runs in full trust mode and could access local resources. In other hand Silverlight applications are meant to be web based and they runs inside a web browser in isolation (sandbox environment).
Silverlight applications are becoming more popular everyday because of ease to develop and user experience. People more often consider developing a web component to be reuse in windows forms environment. It mostly considered as a good option for migration projects where a big enterprise system is migrated in phases.
Possible solution(s)
In order to host a Silverlight application within a windows form there are two options.
- Silverlight in Winform:Host web browser control in winform and communicate with Silverlight application.
While designing the Silverlight component or application, design everything carefully utilizing shared classes and linked classes concept of VS.net. It will help putting complex code in common classes to be referenced in a Silverlight and WPF based projects. WPF component could be easily hosted inside a typical winform application. Shared classes will be useful to ensure any change done from Silverlight perspective is not breaking WPF and vice-a-versa.
- WPF and Silverlight:Design the application in such a way that common components could be created in form of shared classes to help building a Silverlight and WPF specific control.
While designing the Silverlight component or application, design everything carefully utilizing shared classes and linked classes concept of VS.net. It will help putting complex code in common classes to be referenced in a Silverlight and WPF based projects. WPF component could be easily hosted inside a typical winform application. Shared classes will be useful to ensure any change done from Silverlight perspective is not breaking WPF and vice-a-versa.
There could be other ways of achieving this by separating the communication between two layers by implementing some protocol/process. An approach where windows application could pass information through server. (These will require additional round trip to server)
Option 2is more about planning the structure of the code and introducing a proper development processes specific to project’s need.
Option 1 is often seen as a quick win to host existing Silverlight application in a windows application.
Silverlight in Windows Application:
Following are the steps for accomplishing option 1 approach of solution.
- Within Silverlight application create a dedicated class to communicate with windows application and write all the logic there. Communication between Silverlight and Windows app is necessary to pass information, invoke the method and raise events etc. Let us name it WindowsClient.cs (in Silverlight project)
- Include reference of System.Windows.Browser namespace in the class and mark class as [ScriptableType] to expose the class in the web browser.
- Register this class and give a name to refer the class from web browser using scripting technique (javascript). If we want to call this class as WinClient, we can register it as HtmlPage.RegisterScriptableObject(“WinClient”, this); Now this class will be accessible from javascript and DOM through browser.
- We can create member functions to read from Silverlight and to pass information into Silverlight. Keep in mind that more simple work will leave less security loophole. Simple code will be easy to maintain as well. Make it a practice that information flow should be always from windows client to Read and Push information.
- Let us create a method to accept the information (serialized .net class containing any information to be used in Silverlight application). See following example and notice ScriptableMember attribute highlighted.
[ScriptableMember]
Public void SetInfomation(object serializedInfomation)
{
String message = serializedInformation.ToString();
//there is nothing to stop using a Serialization/DeSerialization wrapper to pack and //unpack information coming from win form application as following
// EventInformation evt = //CustomSerialization.DeserializeEntity<EventInformation>(message);
//now you have information in Silverlight layer so you can use it as per app’s need
}
- Another important thing is to raise some notification or event from Silverlight to notify windows host regarding change in the status. Such event could be session time out, validation error, information message etc. This could be achieved by writing a method to return string of serialized class from Silverlight. When windows client will get notification of any such event, it will read the Silverlight method to see detail and type of information.
[ScriptableMember]
Public string ReadInformationMessage()
{
String usefullInformation = CustomSerialization.SerializeEnttiy<SessionTimedOut>(App.mySessionObject);
Return usefullInformation;
//Point to notice here is that your POCO class being return could contain message, message //type (error, warning, information etc) and anything else
//windows host application should have a utility to transform these messages and execute //relevant code
}
- In windows application create a control to host Silverlight application. Add a web browser control in this custom control.
- Declare a private variable to contain Silverlight application URL.
- Modify the constructer to accept Silverlight application URL. (Alternatively there could be a public method created to inject the URL and force browser to navigate).
- Write the code to navigate browser control to the given URL. Make sure you have registered event handlers of web browser control to handle DocumenCompleted and StatusTextChanged. In order to avoid HTML dialogs appearing to display and script error make webBrowserControl.ScriptErrorsSuppressed = true.
- In the DocumentCompleted event handler check and ensure whether document is loaded and then push your information (serialized entity) into Silverlight by using javascript. Javascript method could be invoked as following example.
String strToBePassed = YourSerializationUtil.Serialze<YourObject>(obj);
object[] script = { “JSMethodSetInformation(‘” + strToBePassed + “‘);” };
webHost.Document.InvokeScript(“eval”, script);
Alternatively you can directly call you javascript method without using Eval by passing array of object as argument.
- In the head section of the html page (or aspx page) writes following code to initialize Silverlight object reference. See example below:
<script type=”text/javascript”>
var slCtl = null;
function initializePlugin(sender, args) {
slCtl = sender.getHost();
}
</script>
- Call above mentioned method using Silverlight plugin’s param tag as following:
<object id=”slShell” data=”data:application/x-silverlight-2,” type=”application/x-silverlight-2″ width=”100%” height=”100%”>
<%– <param name=”Windowless” value=”true”/>–%>
<param name=”source” value=”ClientBin/ShellModule.xap”/>
<param name=”onError” value=”onSilverlightError” />
<param name=”background” value=”white” />
<param name=”minRuntimeVersion” value=”3.0.40624.0″ />
<param name=”autoUpgrade” value=”true” />
<param name=”onLoad” value=”initializePlugin” />
<a href=”http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0″ style=”text-decoration:none”>
<img src=”http://go.microsoft.com/fwlink/?LinkId=108181″ alt=”Get Microsoft Silverlight” style=”border-style:none”/>
</a>
<object>
In this example, whole object block is given to help understanding usages of Param tag.
- Now define Javscript version of methods to be called from winform application and invoke Silverlight method.
<script type=”text/javascript”>
function SetSessionInformation(value)
{
if (slCtl != null)
if (slCtl.Content != null)
slCtl.Content.WinClient.SetInformation(value.toString());
}
function GetInformation(value) {
if (slCtl != null)
if (slCtl.Content != null)
value = slCtl.Content. WinClient.GetInformation();
return value;
}
</script>
- In the above mentioned example it is assumed that there would be two public methods available in Silverlight’s class as scriptable member with name of SetInformation and GetInformation to push and pull the information.
- Another interesting thing is to notify the windows application about any event in Silverlight layer. In Silverlight if there is any event occurred such as Session time out following code could be used to change the status of web browser control.
HtmlPage.Window.SetProperty(“status”, “Silverlight Status Changed”);
- Changing the status message will trigger web browser’s event registered in windows form control (StatusTextChanged). Windows form class than read the Silverlight information as per status changed notification and execute the appropriate code.
Further Suggestions:
These steps are just proof of concept to give a high level view for achieving Silverlight applications within the windows application. As per any existing architecture or guidelines this approach could be extended to fit in the requirement.
It is highly recommended to place these units totally separate to any other part of the application to avoid making these as a dependency of other part of the system. Specific classes could be developed to carry application specific information such as state of business entity, actions, messages (error, warning, information) etc.
It is suggested to encrypt the message while passing between these applications to avoid any data security implications. For general applications standard Base64 encryption would be sufficient, however depending on the data sensitiveness any complex logic could be implemented while serialization process.
Just want to say a BIG thanks for this. I have actually read one of your original article (http://www.sujitksingh.com/silverlight-hosting-in-winform-application.aspx – no longer available) to help with my project on hosting & communicating between the Silverlight control and my Winform.
Keep up the good work.
Jay
@Jay – Sorry for the old link not working, my hosting provider decided to shut down their business. Glad to hear article helped. Cheers