Silverlight Tip: Enumerating embedded resources

November 13, 2009

Today I’ve got a “Call for Help” from one of Silverlight MVPs – Bill Reiss. The mail said:

“I would like to enumerate all items that were marked as Content or Resource in the main XAP file.

If I can’t do both I’d settle for one. Any sample code for this would be greatly appreciated.

Bill”

 

I decided to help with embedded resources, because I did something like this in WPF.

I’ve created sample application, which will display a list of resources in list box – from here it is very easy to use them by name. My sample will load the resource as image.

For application I’ve added 3 sample images and marked them “Resource” in properties:

image

The application UI:

image

XAML for sample:

    <StackPanel x:Name="LayoutRoot" Background="White" Orientation="Vertical">
        <StackPanel Orientation="Horizontal" Margin="5">
            <Button Content="Embedded Resources" Padding="5" Margin="5" x:Name="btnEmbedded" Click="btnEmbedded_Click"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal" Margin="5">
            <StackPanel Orientation="Vertical" Margin="5">
                <TextBlock Text="Embedded Resources:" Margin="5,0"/>
                <ListBox x:Name="lstEmbedded" SelectionChanged="lstEmbedded_SelectionChanged" Margin="5"/>
                <Image x:Name="imgEmbedded" Stretch="Uniform" Width="150" Height="150" Margin="5,0"/>
            </StackPanel>
        </StackPanel>
    </StackPanel

At code behind I have 2 event handler functions. First – to handle button click and get the resources.

First of all I have to open XAP file as a resource:

WebClient wc = new WebClient();
wc.OpenReadCompleted += (s, args) =>
{
   if (args.Error == null)
   {
      //rest will be here
   }
};
wc.OpenReadAsync(new Uri("SL_Resources_Test.xap", UriKind.RelativeOrAbsolute));

When the OpenRead completes, first I have to get the list of assembly parts in XAP using application manifest.

XmlReader reader = XmlReader.Create(Application.GetResourceStream(new StreamResourceInfo(args.Result, null), 
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") }); } } }

Now, when I have a list of all parts (DLLs which could have embedded resources) I will get resources from each one of the DLLs:

List<string> embeddedResources = new List<string>(); //Will use this list as source for ListBox later in code

foreach (var part in parts)
{
   Assembly assy = part.Load(Application.GetResourceStream(new StreamResourceInfo(args.Result, null), 
new Uri(part.Source, UriKind.Relative)).Stream); //Load current assembly string[] resources = assy.GetManifestResourceNames(); //Get embedded resource names foreach (var resource in resources) { ResourceManager rm = new ResourceManager(resource.Replace(".resources",""), assy); //All resources has “.resources” in the name – so I have to get rid of it Stream DUMMY = rm.GetStream("app.xaml"); //Seems like some issue here, but without getting any real stream next statement doesn't work.... ResourceSet rs = rm.GetResourceSet(Thread.CurrentThread.CurrentUICulture, false, true); //to get the actual values - create the table //Dictionary<string, object> table = new Dictionary<string, object>(); IDictionaryEnumerator enumerator = rs.GetEnumerator(); while (enumerator.MoveNext()) { embeddedResources.Add((string)enumerator.Key); //It is also possible to get the value and key instead of just key //object obj2 = enumerator.Value; //table.Add((string)enumerator.Key, obj2); } } } lstEmbedded.ItemsSource = embeddedResources; //Use prepared list as a source for ListBox

Now my embedded resources enumerated.

Second part – use the resource by name when selection changed in the list box:

private void lstEmbedded_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    Uri uri = new Uri(lstEmbedded.SelectedItem.ToString(), UriKind.RelativeOrAbsolute);

    BitmapImage img = new BitmapImage(uri);
    imgEmbedded.Source = img; 
}

 

Running application:

image

image image image

 

Sample source here.

 

Stay tuned for more posts and news to come from PDC09.

 

 

See you at PDC09 and SDP!

Alex

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

19 comments

  1. joeNovember 24, 2009 ב 1:15

    Were you ever going to push the source? This article interested me but I wasn’t able to implement my own take based on the snippets above.

    I’d really appreciate it. It’s a neat idea.

    Reply
  2. Alex GoleshNovember 24, 2009 ב 8:52

    Sample posted! Sorry for delay:)

    Reply
  3. Roulett TrickDecember 31, 2009 ב 18:02

    Sometimes it’s really that simple, isn’t it? I feel a little stupid for not thinking of this myself/earlier, though.

    Reply
  4. Roulett TipDecember 31, 2009 ב 18:23

    Damn, that sound’s so easy if you think about it.

    Reply
  5. online rouletteDecember 31, 2009 ב 18:24

    Great idea, but will this work over the long run?

    Reply
  6. Roulette SpielenJanuary 2, 2010 ב 3:49

    Great idea, thanks for this tip!

    Reply
  7. jetzt roulette spielenJanuary 2, 2010 ב 3:54

    Damn, that sound’s so easy if you think about it.

    Reply
  8. Online RouletteJanuary 2, 2010 ב 19:29

    Hey, ok, I get it, I guess – but does this really work?

    Reply
  9. Tip TricksJanuary 12, 2010 ב 23:35

    This brings me to an idea:…

    Reply
  10. TagesgeldFebruary 4, 2011 ב 6:28

    Da frage ich mich beim Durchlesen von blogs.microsoft.co.il ja schon, ob man selbst nicht komplett auf den Kopf gefallen ist. Herzlichen Dank fur deine Erlauterungen

    Reply
  11. blogs.microsoft.co.ilApril 4, 2011 ב 4:33

    Silverlight tip enumerating embedded resources.. WTF? :)

    Reply
  12. blogs.microsoft.co.ilApril 22, 2011 ב 16:02

    Silverlight tip enumerating embedded resources.. I like it :)

    Reply
  13. E CigaretteApril 27, 2011 ב 13:16

    Monument to the author posed for this:)

    Reply
  14. goldfishkaMay 7, 2011 ב 22:01

    Super! All would be well written:)

    Reply
  15. zhenskayaobuvMay 28, 2011 ב 7:47

    Hooray!, The one who wrote nishtyak wrote!

    Reply