【问题标题】:How to get the names of all resources in a resource file如何获取资源文件中所有资源的名称
【发布时间】:2009-06-16 09:48:49
【问题描述】:

在 Visual Basic 项目中,我添加了一个包含一堆图像的资源文件 (resx)。

现在我想查询图像的名称。 如果我在 Visual Studio IDE 的设计器视图中打开 resx 文件并选择一个图像,属性网格会显示一个名称属性(默认为“没有扩展名但可以更改的文件名)。

背景是我有一个在运行时创建的图像列表,并填充了资源文件中的图像。为了能够通过键访问这些图像,我必须进行设置。

我的代码看起来像这样(所有东西都是硬编码的):

Dim imagelist as new Imagelist
imageList.Images.Add("A", My.Resources.MyImages.A)
imageList.Images.Add("B", My.Resources.MyImages.B)
imageList.Images.Add("C", My.Resources.MyImages.C)
imageList.Images.Add("D", My.Resources.MyImages.D)
imageList.Images.Add("E", My.Resources.MyImages.E)
....
imageList.Images.Add("XYZ", My.Resources.MyImages.XYZ)

我想实现这个:

Dim imagelist as new ImageList

For Each img in GetMeAllImagesWithNameFromMyResourceFile
    imageList.Images.Add(img.Name, img.ImageFile)
Next

其中 Name 是一个字符串,ImageFile 是一个 System.Drawing.Bitmap

【问题讨论】:

    标签: vb.net visual-studio resx


    【解决方案1】:

    看看这段代码是否有帮助。

        Dim runTimeResourceSet As Object
        Dim dictEntry As DictionaryEntry
    
        runTimeResourceSet = My.Resources.ResourceManager.GetResourceSet(System.Globalization.CultureInfo.CurrentCulture, False, True)
        For Each dictEntry In runTimeResourceSet
            If (dictEntry.Value.GetType() Is GetType(Icon)) Then
                Console.WriteLine(dictEntry.Key)
            End If
        Next
    

    我以 Icon 为例,如果你使用的是 Bitmap,则必须更改它。

    编辑:您将不得不使用 dictEntry.Value 的引用并查看它如何用于将其添加到 imagelist。

    【讨论】:

    • 效果很好,正是我想要的。只有 2 个小改动: 首先:GetResourceSet 的第二个参数应该为 true(即使 Resouce 尚未加载也能获得引用)。第二: Icon.GetType() 将不起作用,因为您没有实例化它,它应该是 GetType(Icon) 。也许你可以编辑你的帖子来纠正这个问题。
    • 如果我没记错的话,这段代码适用于 Icon.GetType()。我将根据您的建议将其更改为 GetType(Icon)。
    • 它将在 Windows 窗体中工作,因为您有一个 Form1.Icon 属性,该属性返回窗体的实际图标。但是 GetType(Icon) 是干净的解决方案。
    【解决方案2】:

    以下是用C#编写的,你应该可以很容易地把它翻译成VB。

    Assembly executingAssembly = GetExecutingAssembly();
    
    foreach (string resourceName in executingAssembly.GetManifestResourceNames())
    {
        Console.WriteLine( resourceName );
    }
    

    现在您已经拥有所有资源名称,您可以遍历列表并执行以下操作:

    foreach(string s in executingAssembly.GetManifestResourceNames())
    {
        if (s.EndsWith(".bmp"))
        {
            imgStream = a.GetManifestResourceStream(s);
            if (imgStream != null)
            {                    
                bmp = Bitmap.FromStream(imgStream) as Bitmap;
                imgStream.Close();
            }   
        }
    }
    

    我没有尝试过,但它应该可以工作。

    【讨论】:

    • GetManifestResourceNames 枚举我的所有资源(例如 [WindowsApplication1.Images.resources | WindowsApplication1.Resources.resources | WindowsApplication1.Form1.resources] )。不是我想要的。
    【解决方案3】:

    试试这样的:

    Dim reader As New ResXResourceReader(resxFilePath)
    
    Dim en As IDictionaryEnumerator
    en = reader.GetEnumerator()
    
    While en.MoveNext()
        Console.WriteLine("Resource Name: [{0}] = {1}", en.Key, en.Value)
    End While
    
    reader.Close()
    

    您可以在this link 找到更多可以帮助您的示例。示例是用 C# 编写的,但在 vb.net 上修改它们并不难

    【讨论】:

    • 我想他想加载嵌入式资源。上述代码适用于外部 RESX 文件。
    【解决方案4】:

    虽然上述答案为我指明了正确的方向,但我添加了一个单独的答案来阐明 GetResourceSet 的使用和随后的图像加载:

            Dim resSet As Resources.ResourceSet = My.Resources.ResourceManager.GetResourceSet(Globalization.CultureInfo.InvariantCulture, True, False)
            For Each de As DictionaryEntry In resSet
                If (de.Value.GetType() Is GetType(Bitmap)) Then
                    m_Icons.Add(de.Key, My.Resources.ResourceManager.GetObject(de.Key))
                End If
            Next
    

    My.Resources.ResourceManager.GetResourceSet 中的参数注意以下几点:

    • 使用 不变文化
    • True 是加载资源所必需的,因为此时在我的类库中我还没有访问资源集,这会强制加载它。这似乎是@bcrgen-steinblock 在他的评论中的意思,但在随后的编辑中被误解了
    • false 对我来说没问题,因为我没有设置后备/默认资源

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-09
      • 2011-03-29
      • 2015-01-30
      • 2012-04-23
      • 2021-09-25
      相关资源
      最近更新 更多