1

我正在开发一个 Windows 窗体应用程序,我将使用一组图像(想想图标)。根据主题,必须选择不同的图像集(我稍后将使用 绘制它们Bitmap)。

我正在考虑将图像存储在单独的文件中(存档文件?dll?),然后在运行时从主应用程序加载它们。最有效的方法是什么?

感谢您的阅读。

4

3 回答 3

3

考虑到少数情况,我将回答这个问题。

  1. 这个图像经常变化吗?然后使用基于目录的方法,将其存储在目录中并加载。可能你可以有一个包含这些文件名称的 xml 来加载。所以文件(图像)中的名称更改,只需更改 xml。

  2. 这些文件永远不会改变?然后只需将它们作为资源嵌入,这样它将嵌入到您的 exe/dll 中,并且不会损坏图像。

通常我看到人们不做嵌入。

于 2011-09-03T17:37:25.603 回答
0

不确定您是否得到了您正在寻找的答案。这是创建资源dll的一步一步

  1. 在visual studio中新建项目,类库
  2. 将您的资源(图片)添加到项目中(添加现有项目)
  3. 对于每个资源,在属性窗口中,将 Build Action 设置为 Embedded resource
  4. 编译库,生成一个dll
  5. 在您的 winforms 应用程序中,您现在可以在运行时加载此程序集(代码 #1)
  6. 加载所需的资源流并将其保存到 Bitmap 对象(代码 #2)

代码 #1

Assembly ambly = Assembly.LoadFile(pathToDll);

代码 #2

BitMap bitMap;
// where "ns" is the default namespace of the resource project    
using (Stream resourceStream = ambly.GetManifestResourceSream("ns.image.jpg"))
{
      bitMap = BitMap.FromStream(resourceStream);
}

这些是用于嵌入资源并在运行时加载它们的基本技术。

现在,由于您正在考虑拥有不同的主题,并将每个主题的资源存储在不同的库中,因此您应该有一个接口来指定某种资源管理器,在您的主应用程序中定义。

一个例子

interface IThemeResourceProvider
{
     Stream LoadBigLogo();
     Stream LoadSmallLogo();
} 

然后在您的资源库中实现该接口

public class ThemeResourceProvider : IThemeResourceProvider
{
    public Stream LoadBigLogo()
    {
         Assembly ambly = Assembly.GetExecutingAssembly();
         return ambly.GetManifestResourceStream("namespace.image.jpg");
    }

    (...)
}

最后,不是直接在主应用程序中加载资源,而是实例化资源库中的 IThemeResourceProvider

 Assembly assembly = Assembly.LoadFile(pathToDll);

 var results = from type in assembly.GetTypes()
               where typeof(IThemeResourceProvider).IsAssignableFrom(type)
               select type;

现在您IEnumerable<Type>在该列表中有一个。通常,您只有一个,但使用这种方法,您还可以托管多组资源,并在同一个资源 dll 中实现多个 IThemeResourceProvider。例如,您可以使用名称标识每个 IThemeResourceProvider,或者作为属性,或者[Attribute]在您的各种实现中使用自定义装饰。我会把剩下的留给你来解决。

但这里是如何在你的列表中实例化 IThemeResourceProviders

foreach (var providerType in results)
{
     var constructorInfo = providerType.GetConstructor(Type.EmptyTypes);
     IThemeResourceProvider provider = constructorInfo.Invoke(null);
}

最后,使用这些提供程序之一获取位图:

BitMap bitMap;
using (Stream resourceStream = provider.LoadBigLogo())
{
      bitMap = BitMap.FromStream(resourceStream);
}
于 2011-09-10T08:57:06.523 回答
0

您是否考虑过使用 resx 文件(资源文件)?这样,您可以嵌入任何图像(图标)或任何您喜欢的内容,并决定仅加载基于您的主题所需的资源文件(资源文件可以根据您的主题名称命名)。好像是本地化时遇到的同样的问题,不是吗?但是要知道这是否是最好的方法(性能、内存等),我不能说。

于 2011-09-10T06:24:47.197 回答