1 / 24

Tips, Tricks, and Techniques for Building Killer Silverlight Apps

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

mick
Download Presentation

Tips, Tricks, and Techniques for Building Killer Silverlight Apps

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Tips, Tricks, and Techniques for Building Killer Silverlight Apps Jeff Prosise http://www.wintellect.com/CS/blogs/jprosise/default.aspx http://twitter.com/#!/jprosise

  2. 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!

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

  4. Dynamic Assembly Loading

  5. 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

  6. Enumerating Assemblies in a XAP StreamResourceInfosri = 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") }); } } }

  7. Loading Enumerated Assemblies foreach (AssemblyPart part in parts) { Stream assembly = Application.GetResourceStream (sri, new Uri(part.Source, UriKind.Relative)).Stream; part.Load(assembly); }

  8. Dynamic XAP Loading

  9. 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?

  10. ObservableResources public class ObservableResources<T> : INotifyPropertyChanged { public event PropertyChangedEventHandlerPropertyChanged; 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")); } }

  11. Enumerating Satellite Assemblies StreamResourceInfosri = 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") }); } } }

  12. 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); } }

  13. Dynamic Localization

  14. 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

  15. Do-Nothing Content Loader public class CustomContentLoader : INavigationContentLoader { private PageResourceContentLoader _loader = new PageResourceContentLoader(); public IAsyncResultBeginLoad(Uri targetUri, Uri currentUri, AsyncCallbackuserCallback, object asyncState) { return _loader.BeginLoad(targetUri, currentUri, userCallback, asyncState); } public boolCanLoad(Uri targetUri, Uri currentUri) { return _loader.CanLoad(AddFileNameExtension(targetUri), currentUri); } public void CancelLoad(IAsyncResultasyncResult) { _loader.CancelLoad(asyncResult); } public LoadResultEndLoad(IAsyncResultasyncResult) { return _loader.EndLoad(asyncResult); } }

  16. Registering a Content Loader <nav:Frame x:Name="Main" Source="Home"> <nav:Frame.ContentLoader> <local:CustomContentLoader /> </nav:Frame.ContentLoader> </nav:Frame>

  17. Dynamic Page Loading

  18. 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

  19. 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; } }

  20. 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>

  21. Behaviors

  22. 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 bloghttp://blogs.msdn.com/belux • Join us on Facebookhttp://www.facebook.com/msdnbehttp://www.facebook.com/msdnbelux • LinkedIn: http://linkd.in/msdnbelux/ • Twitter: @msdnbelux DownloadMSDN/TechNet Desktop Gadgethttp://bit.ly/msdntngadget

  23. TechDays 2011 On-Demand • Watchthis session on-demand via Channel9http://channel9.msdn.com/belux • Download to your favorite MP3 or video player • Get access to slides and recommended resources by the speakers

  24. THANK YOU

More Related