As with any client delivered over the browser, one key part of user experience is enabling the user experience to start – i.e. not having the user wait 10 minutes until they can do anything. The flip side is that RIAs many times have large assemblies and content that needs to be downloaded for to put the Rich in RIA.
Silverlight achieves this by allowing the developer to use a WebClient object to download a stream of whatever resource it has at a known Uri. In our situation we want to download a Silverlight Control Library containing our Rich controls after the application has started.
The completed solution can be downloaded from here.
1. Create a Silverlight application project called LoadOnDemand and choose to add a web project for testing
2. Note the physical location of the web project ClientBin folder - you will need this later
3. Add a new project of type Silverlight Control Library to the LoadOnDemand solution called CustomControls
4. Add a new user control to the CustomControls project called LoadOnDemandCustomControl
5. In the LoadOnDemandCustomControl.xaml file remove the width and height attributes from the User Control declaration
6. In the LoadOnDemandCustomControl.xaml file replace the LayoutRoot grid with the following XAML
<Grid x:Name="LayoutRoot" >
<Border BorderThickness="5" CornerRadius="12" BorderBrush="Firebrick" Background="Orange" >
<StackPanel Orientation="Vertical" >
<TextBlock Text="Custom Control"></TextBlock>
<TextBlock Text="Loaded @ " x:Name="txtLoaded"></TextBlock>
7. In the LoadOnDemandCustomControl.xaml.cs file replace the constructor with the following code
this.Loaded += new RoutedEventHandler(LoadOnDemandCustomControl_Loaded);
void LoadOnDemandCustomControl_Loaded(object sender, RoutedEventArgs e)
txtLoaded.Text += DateTime.Now.ToString();
This displays the time the control is loaded in the display of the control.
8. In the build properties of the CustomControls project, set the Output Path to the location of the web application’s ClientBin directory (the physical location you noted in step 2).
9. In the LoadOnDemand project, add a reference to the CustomControls project and mark the Copy Local property to False.
10. In the MainPage.xaml file in the LoadOnDemand project replace the LayoutRoot Grid with the following XAML
<StackPanel x:Name="stkControls" Orientation="Vertical" Width="200" HorizontalAlignment="Center" VerticalAlignment="Center" >
<Button Content="Load Control" x:Name="btnLoad" Click="btnLoad_Click"></Button>
This layout provides a stack panel containing a button. When the button is clicked a Silverlight Control Library will be downloaded and a user control from that library will be added to the stack panel
11. In the MainPage.xaml.cs file paste the following code after the constructor
private bool customControlsLoaded = false;
private void btnLoad_Click(object sender, RoutedEventArgs e)
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
wc.OpenReadAsync(new Uri("CustomControls.dll", UriKind.Relative));
void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
if (e.Error == null && e.Result != null)
AssemblyPart part = new AssemblyPart();
customControlsLoaded = true;
private void AddCustomControl()
CustomControls.LoadOnDemandCustomControl ctrl = new CustomControls.LoadOnDemandCustomControl();
If the CustomControls Silverlight Controls Library has not been loaded before, then the button click event creates a WebClient object and defines an event handler for the open read completed event. The resource Uri for the CustomControls.dll Silverlight Control Library is provided for the OpenReadAsync function. Note the Uri is relative as the Silverlight Control Library sits in the ClientBin folder of the web app – the same location as the XAP file that this Silverlight Application is loaded from and where we set the output path for the build of the CustomControls project.
Once the assembly has been downloaded it is loaded into an AssemblyPart (which loads the assembly into the current Silverlight application context). An instance of the LoadOnDemandCustomControl from the control library is then created and added to the stack panel in the UI.
If the CustomControls library has already been loaded when the button is clicked then the library doesn’t need to be loaded and a custom control can simply be added to the stack panel.
12. Add a breakpoint to the btnLoadClick event in the MainPage.xaml.cs file to follow the code and verify whether the CustomControls library is reloaded after the first time.
13. Run the application
14. Click the button - the breakpoint will be hit and you will see that the CustomControls library is downloaded. Follow the code to see the the custom control being added to the stack panel. You will see the custom control displayed with the date and time when it was loaded.
15. Click the button a few more times and see that the custom control library is not downloaded again and see more custom controls displayed with their respective dates and times of loading.
Congratulations!!!! You have implemented loading on demand of a Silverlight Control Library
What have we done?
We have created a Silverlight Control Library and enabled it to be downloaded on demand.
We have created a Silverlight application that is coded with strong typing for the user controls in the Silverlight Control Library.
We have programmatically controlled the download of the Silverlight Control Library and it’s loading into the current application context of the Silverlight Application.
We have instantiated objects of the user control in the dynamically loaded Silverlight Control Library.
Using load on demand will allow you to control when resources and assemblies are downloaded within your application and will stop the user from having to wait for the whole application to download before being able to use it. These methods allow the developer very granular control and logic of how and when to load their dependencies; for instance you could make choices of what logic to download based on the role of the logged in user or what functionality the user chooses to use. Why load more than you need to consume?