MULTIMEDIA

Silverlight Recipes : Managing Embedded Resources

7/13/2011 6:14:19 PM

1. Problem

You want to store resources inside of the Silverlight application container (the .xap file) and retrieve them at runtime, as opposed to simply putting the resources, such as images, in the file system and referencing as a URL.

2. Solution

Use the Assembly.GetManifestResourceNames and Assembly.GetManifestResourceStream methods to enumerate and retrieve resources embedded in a Silverlight application.

3. How It Works

To read embedded resources, you have to first embed them into the application. To embed resources such as images, video, and XML data, add the resources to the Silverlight application project, and set the build action for each resource to Embedded Resource. The next time you build the project, the resources will be embedded into the application.

To obtain a list of resources available in the application, you can call Assembly.GetManifestResourceNames to obtain the names as a string array:

Assembly app = Assembly.GetExecutingAssembly();
string[] resources = app.GetManifestResourceNames();

Once you have the name of the desired resource, you can call Assembly.GetManifestResourceStream to obtain the resource as a byte array and then convert it to the appropriate type.

4. The Code

The sample application for this recipe includes three images that have been configured to be an embedded resource in the assembly. The UI for the recipe has a simple gradient for the root Grid Background, a Button named RetrieveResourceNames to retrieve the resource names of embedded resources that are available, and a ListBox control named ResourceNames to display the names.

The application also has a Border control to provide a color outline for a nested Image control, which is where the embedded resources are displayed. You apply a simple 5% skew transformation to the Border.

When the application runs, the user can click the button to obtain a list of available resources, which includes the three images. Selecting an image name in the ListBox displays the image within the Border control. Figure 1 shows the application UI with an image selected.

Figure 1. Recipe 10 UI with an image selected

The images are named Acadia1, Acadia2, and Acadia3 in the project file system. However, when they are embedded into the application binary, the namespace is added to the filename. Keep this in mind when loading resources if you're not first getting their names using the GetManifestResourceNames.

Notice the first resource listed in Figure 1. This resource is automatically generated as part of compiling and generating the application. When the first resource is clicked, simply ignore it since it isn't an image.

This application has a simple UI to demonstrate the functionality but here is the minor configuration: the ListBox is transparent, and the foreground color for the items is orange; the ListBox's Foreground property is configured with a SolidColorBrush to provide the orange text; the ListBox's Background property is set to Transparent, which results in the transparency; and the ListBox's ItemContainerStyle defaults to a white background, which is modified with this XAML for the style:

<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">

<Setter Property="Background" Value="Transparent"/>
</Style>
</ListBox.ItemContainerStyle>

Styles can also be resources that are loaded using the StaticResource markup extension.

The code file has two events: one to retrieve the list of resource names for the button click event and another that loads the resource into the Image object. As mentioned earlier, the GetManifestResourceNames returns a string array of resource names, so that is easy enough to do. The somewhat more complex code is actually retrieving the resource as a byte array and converting it to an image.

You use a stream object to obtain the array of bytes that represents the binary resource data. You create a new System.Windows.Media.Imaging.BitMapImage object and call the SetSource method, passing in the stream of bytes:

BitmapImage bImage = new BitmapImage();
bImage.SetSource(stream);

This code loads the bytes into a BitmapImage object, which is then set as the Source for the Image control named ImageDisplay that renders the image to the screen. Listings 1 and 2 have the full code listing.

Listing 1. Recipe 10's MainPage.xaml File
<UserControl x:Class="Ch02_ProgrammingModel.Recipe2_10.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.41*"/>
<ColumnDefinition Width="0.59*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.172*"/>
<RowDefinition Height="0.828*"/>
</Grid.RowDefinitions>
<Grid.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF000000"/>
<GradientStop Color="#FF696767" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<ListBox x:Name="ResourceNames" Background="Transparent"
HorizontalAlignment="Stretch" Margin="4,4,15,4" Grid.Row="1"
SelectionChanged="ResourceNames_SelectionChanged">
<ListBox.Foreground>


<SolidColorBrush Color="#FFD18726"/>
</ListBox.Foreground>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Background" Value="Transparent"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<Button Height="26.4" HorizontalAlignment="Stretch"
Margin="64,4,74,0" x:Name="RetrieveResourceNames"
VerticalAlignment="Top" Content="Retrieve Resource Names"
d:LayoutOverrides="VerticalAlignment, Height"
Click="RetrieveResourceNames_Click"/>
<TextBlock HorizontalAlignment="Stretch" Margin="53,0,74,4"
VerticalAlignment="Bottom" Text="Select a Resource to Display"
TextWrapping="Wrap" Foreground="#FFFFFFFF" Height="22"/>
<Border Margin="29.2129993438721,
−15.206000328064,32.7869987487793,35.6059989929199"
HorizontalAlignment="Stretch" BorderBrush="#FF000000"
x:Name="ImageBorder" RenderTransformOrigin="0.5,0.5"
Visibility="Collapsed" Height="310.8" VerticalAlignment="Stretch"
Grid.Column="1" Grid.ColumnSpan="1" Grid.Row="1" Grid.RowSpan="1"
d:LayoutOverrides="Height">
<Border.Background>
<SolidColorBrush Color="#FFD28826"/>
</Border.Background>
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform AngleX="5" AngleY="5"/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
<Image x:Name="ImageDisplay" Margin="5,5,5,5" Width="400"
Height="300" OpacityMask="#FF000000" />
</Border>
</Grid>
</UserControl>


Listing 2. Recipe 10's MainPage.xaml.cs File
using System.IO;
using System.Reflection;
using System.Windows;

using System.Windows.Controls;
using System.Windows.Media.Imaging;

namespace Ch02_ProgrammingModel.Recipe2_14
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}

private void RetrieveResourceNames_Click(object sender, RoutedEventArgs e)
{
Assembly app = Assembly.GetExecutingAssembly();
string[] resources = app.GetManifestResourceNames();
ResourceNames.Items.Clear();
foreach (string s in resources)
{
ResourceNames.Items.Add(s);
}
}
Other  
  •  Silverlight Recipes : Managing XAML Resources
  •  Silverlight Recipes : Updating the UI from a Background Thread
  •  Programming with DirectX : Sound in DirectX - XAudio2
  •  Programming with DirectX : Sound in DirectX - XACT3 (part 2) - XACT3 Demo
  •  Programming with DirectX : Sound in DirectX - XACT3 (part 1) - XACT3 Tools
  •  iPhone 3D Programming : Image-Processing Example: Bloom
  •  iPhone 3D Programming : Anisotropic Filtering: Textures on Steroids
  •  iPhone 3D Programming : Reflections with Cube Maps
  •  Silverlight Recipes : Networking and Web Service Integration - Accessing Resources over HTTP
  •  Silverlight Recipes : Networking and Web Service Integration - Using JSON Serialization over HTTP
  •  Microsoft XNA Game Studio 3.0 : Displaying Images - Using Resources in a Game (part 4) - Filling the Screen
  •  Microsoft XNA Game Studio 3.0 : Displaying Images - Using Resources in a Game (part 3) - Sprite Drawing with SpriteBatch
  •  Microsoft XNA Game Studio 3.0 : Displaying Images - Using Resources in a Game (part 2) - Positioning Your Game Sprite on the Screen
  •  Microsoft XNA Game Studio 3.0 : Displaying Images - Using Resources in a Game (part 1) - Loading XNA Textures
  •  iPhone 3D Programming : Holodeck Sample (part 5) - Overlaying with a Live Camera Image
  •  iPhone 3D Programming : Holodeck Sample (part 4) - Replacing Buttons with Orientation Sensors
  •  iPhone 3D Programming : Holodeck Sample (part 3) - Handling the Heads-Up Display
  •  iPhone 3D Programming : Holodeck Sample (part 2) - Rendering the Dome, Clouds, and Text
  •  iPhone 3D Programming : Holodeck Sample (part 1) - Application Skeleton
  •  Building LOB Applications : Printing in a Silverlight LOB Application
  •  
    Most View
    Ditch Your Laptop For Your Phone (Part 5)
    BitFenix Prodigy - Undoubtedly The Best
    Which Is The Real Best-Seller Ultrabook? (Part 1) - Asus Zenbook Prime, Acer Aspire S5, HP Folio 13-2000
    Top 10 Cameras - Jan 2013
    The End Of The Beginning Or The Beginning Of The End? (Part 1)
    SharePoint 2010 : Business Intelligence - Excel Services (part 1) - Accessing Excel Services Over REST
    Powered By Windows (Part 2) - Toshiba Satellite U840 Series, Philips E248C3 MODA Lightframe Monitor & HP Envy Spectre 14
    Space Tech - The Future Of Ultra HD Explained
    Gigabyte GA-F2A85X-UP4 Mainboard & AMD A10-5800K Processor Review (Part 8)
    Reference 3A Episode Loudspeaker
    Top 10
    G-360 And G-550 Power Supply Devices Review (Part 4)
    G-360 And G-550 Power Supply Devices Review (Part 2)
    Canon IXUS 140 Camera - Great Color Reproduction
    Nikon Coolpix S5200 Camera - 10fps Continuous Shooting Mode
    Corsair Neutron GTX 240GB - A Fast Performing SSD
    G-360 And G-550 Power Supply Devices Review (Part 3)
    G-360 And G-550 Power Supply Devices Review (Part 1)
    OCZ Vector 256GB - One Of The Dominant Names In SSD
    Don’t Pay For Office 2013 (Part 2)
    Don’t Pay For Office 2013 (Part 1)