2011-09-03 58 views
1

我正在开发一个Windows窗体应用程序,我将使用图像集(思考图标)。根据主题,必须选择不同的图像集(我将在稍后使用Bitmap绘制它们)。为Windows窗体存储图像集的最佳方法

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

谢谢您的阅读。

回答

2

我会回答这个考虑几个场景。

  1. 该图像经常变化吗?然后进入基于目录的认证,将其存储在一个目录中并加载它。也许你可以有一个XML文件加载这些文件的名称。所以在文件(图像)名称更改,只需更改xml。

  2. 这些文件从不改变?然后,将这些资源嵌入到您的exe/dll中,并将它们嵌入到资源中,而不会破坏图像。

通常我看到人们没有做嵌入。

+0

如何嵌入图像作为资源,创造每个主题都有独立的资源? – csq

+1

在visual studio中,转到项目属性和资源。有选择图像并添加。用VS玩多一点;) – Zenwalker

+0

那么我将如何在另一个项目中使用这些图像呢? – csq

0

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

0

不知道你是否得到了你正在寻找的答案。这里有一个一步一步创建资源DLL

  1. Visual Studio创建一个新的项目,类库
  2. 添加您的资源(图片)到项目(添加的项目)
  3. 对于每个资源,在属性窗口,设置生成操作嵌入的资源
  4. 编译库,生成一个DLL
  5. 在你的WinForms应用程序,你现在可以在运行时加载这个组件(编号#1)
  6. 加载资源流你想要并将其保存到一个位图对象(代码#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中实现多个IThemeResourceProviders。你可以例如用名称标识每个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); 
} 
+0

这种方法在性能上有什么不同吗? –

相关问题