Docstoc

Tips_ Tricks_ and Techniques for Building Killer Silverlight Apps

Document Sample
Tips_ Tricks_ and Techniques for Building Killer Silverlight Apps Powered By Docstoc
					Tips, Tricks, and Techniques for
Building Killer Silverlight Apps
Jeff Prosise
http://www.wintellect.com/CS/blogs/jprosise/default.aspx
http://twitter.com/#!/jprosise
Dynamic Assembly Loading
• AssemblyPart class represents an assembly that's part of a
  Silverlight application
   • Assemblies typically packaged in XAPs
   • AssemblyPart.Load loads assemblies into appdomains at run-
      time
   • The key to dynamic assembly loading, but…
• Beware the JIT compiler!




                                                                  2
Loading an Assembly
 WebClient wc = new WebClient();
 wc.OpenReadCompleted += OnOpenReadCompleted;
 wc.OpenReadAsync(new Uri("Widget.dll", UriKind.Relative));
       .
       .
       .
 private void OnOpenReadCompleted(object sender,
     OpenReadCompletedEventArgs e)
 {
     if (e.Error == null)
     {
         AssemblyPart part = new AssemblyPart();
         part.Load(e.Result);
     }
 }




                                                              3
DEMO
Dynamic Assembly Loading
Dynamic XAP Loading
• XAPs can be loaded dynamically, too
   • Download with WebClient
   • Extract AppManifest.xaml from XAP and enumerate
     assemblies ("parts")
   • Extract assemblies and load with AssemblyPart.Load
• Create class-library XAP by starting with Silverlight Application,
  not Silverlight Class Library
Enumerating Assemblies in a XAP
 StreamResourceInfo sri = new StreamResourceInfo(xap, null);
 XmlReader reader = XmlReader.Create
     (Application.GetResourceStream(sri,
     new Uri("AppManifest.xaml", UriKind.Relative)).Stream);
 AssemblyPartCollection parts = new AssemblyPartCollection();

 if (reader.Read())
 {
     reader.ReadStartElement();
     if (reader.ReadToNextSibling("Deployment.Parts"))
     {
         while (reader.ReadToFollowing("AssemblyPart"))
         {
             parts.Add(new AssemblyPart()
                 { Source = reader.GetAttribute("Source") });
         }
     }
 }
                                                                6
Loading Enumerated Assemblies
 foreach (AssemblyPart part in parts)
 {
     Stream assembly = Application.GetResourceStream
         (sri, new Uri(part.Source, UriKind.Relative)).Stream;
     part.Load(assembly);
 }




                                                                 7
DEMO
Dynamic XAP Loading
Dynamic Localization
• Silverlight supports RESX localization
   • Create resource DLLs from RESX files
       • Resource DLLs == Satellite assemblies
   • Data-bind XAML elements to auto-generated
      ResourceManager wrapper
• Two challenges
   • How do you switch languages at run-time?
   • How do you download satellite assemblies on demand rather
      than embed them in the XAP?
ObservableResources
 public class ObservableResources<T> : INotifyPropertyChanged
 {
     public event PropertyChangedEventHandler PropertyChanged;
     private static T _resources;

     public T LocalizationResources { get { return _resources; } }

     public ObservableResources(T resources)
     {
         _resources = resources;
     }

     public void UpdateBindings()
     {
         if (PropertyChanged != null)
             PropertyChanged(this,
                 new PropertyChangedEventArgs("LocalizationResources"));
     }
 }


                                                                           10
Enumerating Satellite Assemblies
 StreamResourceInfo sri = new StreamResourceInfo(xap, null);
 XmlReader reader = XmlReader.Create
     (Application.GetResourceStream(sri,
     new Uri("AppManifest.xaml", UriKind.Relative)).Stream);
 AssemblyPartCollection parts = new AssemblyPartCollection();

 if (reader.Read())
 {
     reader.ReadStartElement();
     if (reader.ReadToNextSibling("Deployment.Parts"))
     {
         while (reader.ReadToFollowing("AssemblyPart"))
         {
             parts.Add(new AssemblyPart()
                 { Source = reader.GetAttribute("Source") });
         }
     }
 }
                                                                11
Loading Satellite Assemblies
 foreach (AssemblyPart part in parts)
 {
     if (part.Source.ToLower().Contains("resources.dll"))
     {
         Stream assembly = Application.GetResourceStream
             (sri, new Uri(part.Source, UriKind.Relative)).Stream;
         part.Load(assembly);
     }
 }




                                                                     12
DEMO
Dynamic Localization
Dynamic Page Loading
• Navigation framework provides infrastructure for multi-page apps
• Default content loader loads pages from XAP
   • PageResourceContentLoader
   • No built-in support for remote XAPs
• Custom content loaders can load them from anywhere
   • -INavigationContentLoader
Do-Nothing Content Loader
 public class CustomContentLoader : INavigationContentLoader
 {
     private PageResourceContentLoader _loader = new PageResourceContentLoader();

     public IAsyncResult BeginLoad(Uri targetUri, Uri currentUri,
         AsyncCallback userCallback, object asyncState)
     {
         return _loader.BeginLoad(targetUri, currentUri, userCallback, asyncState);
     }

     public bool CanLoad(Uri targetUri, Uri currentUri)
     {
         return _loader.CanLoad(AddFileNameExtension(targetUri), currentUri);
     }

     public void CancelLoad(IAsyncResult asyncResult)
     {
         _loader.CancelLoad(asyncResult);
     }

     public LoadResult EndLoad(IAsyncResult asyncResult)
     {
         return _loader.EndLoad(asyncResult);
     }
                                                                                      15
 }
Registering a Content Loader
 <nav:Frame x:Name="Main" Source="Home">
   <nav:Frame.ContentLoader>
     <local:CustomContentLoader />
   </nav:Frame.ContentLoader>
 </nav:Frame>




                                           16
DEMO
Dynamic Page Loading
Behaviors
• Combine triggers and actions into one package
• Useful when user-input events and actions taken in response to
  those events are tightly bound
   • e.g., drag behavior requires coupling of
     MouseLeftButtonDown, MouseMove, and
     MouseLeftButtonUp events
• Derive from Behavior or Behavior<T>
   • Override OnAttached and OnDetaching
   • AssociatedObject property references attachee




                                                                   18
Implementing a Behavior
 public class DisappearBehavior : Behavior<UIElement>
 {
     protected override void OnAttached()
     {
         base.OnAttached();
         AssociatedObject.MouseLeftButtonDown += OnClick;
     }

     protected override void OnDetaching()
     {
         base.OnDetaching();
         AssociatedObject.MouseLeftButtonDown -= OnClick;
     }

     private void OnClick(object sender, MouseButtonEventArgs e)
     {
         AssociatedObject.Visibility = Visibility.Collapsed;
     }
 }                                                                 19
Applying a Behavior
 xmlns:local="clr-namespace:namespace"
 xmlns:i="clr-namespace:System.Windows.Interactivity;
   assembly=System.Windows.Interactivity"
     .
     .
     .
 <Rectangle Width="300" Height="200" Fill="Red">
   <i:Interaction.Behaviors>
     <local:DisappearBehavior />
   </i:Interaction.Behaviors>
 </Rectangle>




                                                        20
DEMO
Behaviors
Stay up to date with MSDN Belux
• Register for our newsletters and stay up to date:
  http://www.msdn-newsletters.be
   • Technical updates
   • Event announcements and registration
   • Top downloads
• Follow our blog                                            Download
  http://blogs.msdn.com/belux                       MSDN/TechNet Desktop Gadget
• Join us on Facebook                                http://bit.ly/msdntngadget
  http://www.facebook.com/msdnbe
  http://www.facebook.com/msdnbelux
• LinkedIn: http://linkd.in/msdnbelux/
• Twitter: @msdnbelux
TechDays 2011 On-Demand
• Watch this session on-demand via Channel9
  http://channel9.msdn.com/belux
• Download to your favorite MP3 or video player
• Get access to slides and recommended resources by the speakers
THANK YOU

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:4
posted:1/7/2013
language:English
pages:24