Answered by:
Load usercontrol on demand

Question
-
Hello,
I have a silverlight application that's getting pretty big. It has several expanders and the code is something like this (simplified here for better understanding):
<UserControl x:Class="TestProject.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:section="clr-namespace:TestProject"
Width="1024" >
<Grid x:Name="LayoutRoot"
Background="White">
<StackPanel Orientation="Vertical">
<controls:Expander x:Name="Expander1"
Grid.Row="0"
Grid.Column="1"
ExpandDirection="Down"
Header="Section 1">
<section:Section1 x:Name="section 1" />
</controls:Expander>
<controls:Expander x:Name="Expander2"
Grid.Row="0"
Grid.Column="1"
ExpandDirection="Down"
Header="Section 2">
<section:Section2 x:Name="section2" />
</controls:Expander>
</StackPanel>
</Grid>
</UserControl>
Section1 and Section2 are in other xaml files. I want those to load only when I expand the respective expanders (because they still take a while to load), but right now they're being loaded when I start the application. Is there any way I can do it?
Thanks.
Friday, June 5, 2009 7:00 AM
Answers
-
Hi,
Your best bet here is signing up to your Expander.Expanded event and if the Expander.Content is empty than just add it.
Silverlight currently does not support lazy loading. (which is the feature you're asking for)
However, Expander currently has a bug (IMO) that the Expander.Content does not get loaded into the visual tree before the Expander is Expanded for the first time. So you might be in luck since it's fairly similar behaviour to that you're looking for. But, I can't promise we'll maintain that behaviour over time.
Friday, June 5, 2009 7:22 PM
All replies
-
Is this on the right track? It uses the XamlReader to pull the Xaml into a new control on a button click event:
http://silverlight2pointzero.blogspot.com/2009/03/creating-dynamic-control-of-silverlight.html
Friday, June 5, 2009 4:37 PM -
1) Search for OpenReadAsync in the forums.
2) Look at this video http://silverlight.net/learn/learnvideo.aspx?video=65687
3) Here's a little of the code that I use to do this:public void Load () { // Create a web client. WebClient WC = new WebClient (); // Use OpenReadCompleted so that we can get a stream. WC.OpenReadCompleted += new OpenReadCompletedEventHandler ( WC_OpenReadCompleted ); WC.DownloadProgressChanged += new DownloadProgressChangedEventHandler ( WC_DownloadProgressChanged ); // Open a remote stream to the xap file. // Dynamically read the Silverlight application. // The uri is relative to the executing application. WC.OpenReadAsync ( new Uri( xapFileName, UriKind.Relative ) ); } void WC_DownloadProgressChanged ( object sender, DownloadProgressChangedEventArgs e ) { TotalBytesToReceive = e.TotalBytesToReceive; BytesReceived = e.BytesReceived; ProgressPercentage = e.ProgressPercentage; } private void WC_OpenReadCompleted ( object sender, OpenReadCompletedEventArgs e ) { try { // Get the application manifest from "DynamicallyLoadedXap.xap" file. // Then we need to read the manifest to find out what is in it that we can use. // In other words we need to do some introspection. // // "AppManifest.xaml" is relative to the stream bFound in "e.Result" Uri uri = new Uri( "AppManifest.xaml", UriKind.Relative ); StreamResourceInfo SRI1 = new System.Windows.Resources.StreamResourceInfo( e.Result, null ); // From the stream that has been sent in (via e.Result) read the file called "AppManifest.xaml" StreamResourceInfo SRI2 = Application.GetResourceStream ( SRI1, uri ); StreamReader SR = new StreamReader ( SRI2.Stream ); // Read everything in "AppManifest.xaml". Ie. load the application manifest. string AppManifest = SR.ReadToEnd (); // Since we know that the string is xaml we can use a XamlReader. // Get the deployment objects out of the AppManifest.xaml file. XElement deploymentRoot = XDocument.Parse( AppManifest ).Root; List deploymentParts = ( from assemblyParts in deploymentRoot.Elements().Elements() select assemblyParts ).ToList(); // Look at each assembly part. Look at each deployment part. foreach ( XElement xElement in deploymentParts ) { // First look at the name. string source = xElement .Attribute( "Source" ) .Value; Uri uriSource = new Uri ( source, UriKind.Relative ); // Get the assembly from the resource stream. Or "give me the binary that represents // this assembly part name. StreamResourceInfo SRI_app_binary = new StreamResourceInfo ( e.Result, "application/binary" ); StreamResourceInfo streamInfo = Application.GetResourceStream ( SRI_app_binary, uriSource ); //StreamResourceInfo streamInfo = Application.GetResourceStream ( new StreamResourceInfo( e.Result, "application/binary" ), new Uri( source, UriKind.Relative ) ); AssemblyPart asmPart = new AssemblyPart(); if ( TypeName != null && assemblyName != null && source == assemblyName ) { assemblyToUse = asmPart .Load ( streamInfo.Stream ); //Type [] ConstructorParams = new Type [] { typeof( Double ), typeof( Double ), typeof( Double ), typeof( Double ), typeof( Double ) }; Type [] ConstructorParams = new Type [] { typeof( IParentPage ) }; Type T1 = assemblyToUse .GetType ( TypeName, false ); constructor = T1.GetConstructor ( ConstructorParams ); } else { // Must load it even if it is not the one that we are looking for. // // This will load all of the assemblies that our page is dependant on. asmPart .Load ( streamInfo.Stream ); } } // Let the caller know that we are finished. if ( OnLoaded != null ) OnLoaded ( this, new AssemblyLoadedEventArgs( xapFileName + " loaded successfully" ) ); } catch ( Exception E ) { if ( OnFailed != null ) OnFailed ( this, new AssemblyLoadedEventArgs( xapFileName + ", " + E.Message ) ); } }
Friday, June 5, 2009 6:42 PM -
Hi,
Your best bet here is signing up to your Expander.Expanded event and if the Expander.Content is empty than just add it.
Silverlight currently does not support lazy loading. (which is the feature you're asking for)
However, Expander currently has a bug (IMO) that the Expander.Content does not get loaded into the visual tree before the Expander is Expanded for the first time. So you might be in luck since it's fairly similar behaviour to that you're looking for. But, I can't promise we'll maintain that behaviour over time.
Friday, June 5, 2009 7:22 PM