Iterating through App Resources
Again, I am quite new to .NET & WPF so please be patient... I am trying to figure out different ways in which resources can be stored and accessed in a WPF project.
Method 1: Adding a folder to the Project and adding resources to this folder
example: add folder named "images". add 2 images to folder, "image1.png" & "image2.png".
These images can then be accessed in XAML like:
<Image Source="images/image1.png"/>
Method 2: Adding resources to the project using the resource manager, i.e. goto the project properties and select the "Resources" tab and add a couple images : "image3.png" and "image4.png". This method creates a "Resources" folder and creates a Resources.Designer.cs file and some methods for accessing the images.
However, I am not able to programmatically access the images this way - or at least I do not know the correct way to access the images.
interestingly,
int c = Resources.Count;
returns a value of 0 - even though I would assume there are 2 resources.
Also the call to this.FindResource("image3") - causes an exception
All I am interested in are the ways to enumerate the resources in each method. Nothing I have tried has worked...
Réponses
Maybe you missed the last line in my post?
(you can use Application.Current.Resources to access the collection)
Toutes les réponses
I did something similar to what you suggest in your first approach:
<
Application.Resources><Image Source="winter.jpg" Width="800" Height="600" x:Key="winter" />
...
Then in the c# code, to access it:
Image winter = Application
.Current.FindResource("winter") as Image;(you can use Application.Current.Resources to access the collection)
Ok, so I have figured out how to iterate through resources added using Method 2 (Project Resource Manager):
ResourceManager myResMgr = AssembliesAndResources.Properties.Resources.ResourceManager;
if (myResMgr != null)
{
ResourceSet myResSet = myResMgr.GetResourceSet(Thread.CurrentThread.CurrentCulture, true, false);if (myResSet != null)
{
IDictionaryEnumerator myEnum = myResSet.GetEnumerator();
if (myEnum != null)
{
while (myEnum.MoveNext())
{
Console.WriteLine("key = {0}", myEnum.Key.ToString());
Console.WriteLine("value type = {0}", myEnum.Value.GetType().ToString());// pngs = System.Drawing.Bitmap
}
}
}
}
However, there is still the mystery of iterating through resources added using Method 1 (adding a folder to the project). Also, how would you refer to resources added using Method 2 in XAML?
The weird thing is that
<Window x:Class="AssembliesAndResources.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="AssembliesAndResources" Height="300" Width="300"
>
<Grid>
<Image Source="Resources/image3.png"/>
</Grid>
</Window>works in "Design" mode (i.e., the image shows up) - however when you run the app, no image shows up. The following (accessing Method 1 resources) - works in both Design mode and when the app is run:
<Window x:Class="AssembliesAndResources.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="AssembliesAndResources" Height="300" Width="300"
>
<Grid>
<Image Source="images/image1.png"/>
</Grid>
</Window>- Did my previous post not answer how to iterate through resources using method 1?
- I've no interest in resources other than baml resources, so several days ago, I write a simple collection which can hold up the baml resources defined by a specified assembly:
public class XamlResourceCollection : ObservableCollection<XamlResourceItem>
{public XamlResourceCollection(Assembly assembly)
{foreach (String resourceName in assembly.GetManifestResourceNames())
{if (resourceName.ToLower().EndsWith(".g.resources"))
{using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{using (ResourceReader reader = new ResourceReader(stream))
{foreach (DictionaryEntry entry in reader)
{if (entry.Key.ToString().ToLower().EndsWith(".baml"))
{XamlResourceItem item = new XamlResourceItem(entry.Key.ToString(), assembly.GetName().Name);
this.Add(item);
}}}}}}}}public class XamlResourceItem
{private String resourceName;
private Uri resourceUri;
public XamlResourceItem(String resourceName, String containingAssemblyName)
{this.resourceName = resourceName;
this.resourceUri = new Uri("/" + containingAssemblyName + ";component/" + resourceName.ToLower().Replace(".baml", ".xaml"), UriKind.RelativeOrAbsolute);
}public String ResourceName
{get { return resourceName; }
}public Uri ResourceUri
{get { return resourceUri; }
}}
When you can grab the ResourceUri off the XamlResourceItem, you can use LoadComponent() method to instantiate it.
Sheva Musclehead, I guess when I say "iterate" through resources, what I mean is that I am looking for a way to "enumerate" all of the resources - i.e., be able to access the resources in a list without not knowing what the actual resource names or "key" values are - and step through the list one-by-one. Your example was referencing a resource "explicitly" by its name.
I guess for now I will just make sure that all the resources that I want to access this way are included as "embedded" resources in the .resx file and not simply in a folder added to the project.
Thanks
Maybe you missed the last line in my post?
(you can use Application.Current.Resources to access the collection)

