Poser une questionPoser une question
 

TraitéeIterating through App Resources

  • vendredi 10 novembre 2006 17:35jturpin Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     

     

    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

Toutes les réponses

  • vendredi 10 novembre 2006 18:28MuscleHead Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     

    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)

     

  • vendredi 10 novembre 2006 18:31jturpin Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     

    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>

     

     

  • lundi 13 novembre 2006 22:28MuscleHead Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    Did my previous post not answer how to iterate through resources using method 1?
  • mardi 14 novembre 2006 13:31Zhou Yong Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    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

  • mardi 14 novembre 2006 15:27jturpin Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     

    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

     

  • mardi 14 novembre 2006 21:42MuscleHead Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     Traitée

    Maybe you missed the last line in my post?

    (you can use Application.Current.Resources to access the collection)