.net在表单中处理图像资源

时间:2017-02-14 17:57:40

标签: c# .net winforms

我对我的表单引用图像和图标资源时是否处置它有点困惑。具体来说,如果我从设计时资源引用图像/图标或在运行时加载图像,行为是否存在差异。 (.Net4,VS2015,C#)

显然,如果您在设计时将表单的Icon属性设置为Resource,那么当表单关闭时,您不会显式Dispose()。但是,如果你这样设置呢:

this.Icon = Resources.my_default_icon;

关闭该表格时你是否必须处理this.Icon

同样,如果我有一个mini-class只是为了“branding”并且有一个静态Icon对象在运行时加载(可能来自文件,可能只是引用嵌入的Resource),该怎么办?我应该在静态Icon的getter中使用copy-constructor吗?或者可以将其设为公开静态Icon,并允许我的所有表单在_Shown()事件中都有以下单行内容吗?

this.Icon = MyBrandingClass.formIcon;

不确定它是否非常不同,我已经看到一些参考设置在运行时设置图片框的图像并处理图像,但是你会处理嵌入的资源图像吗?如果我将参考文献传递给我的品牌形象,是否可以/我应该省略处理?或者我应该在getter中使用copy-constructor来返回一个新的Image对象,然后在完成表单时总是处理它?<​​/ p>

3 个答案:

答案 0 :(得分:3)

程序应该在不再需要时处理图像,但这并不一定意味着你的代码需要这样做。

在你的第一个例子中:

this.Icon = Resources.my_default_icon;

这实际上转发到ResourceManager类的静态实例。看看Resources.Designer.cs中的代码,您可能会发现它提供了丰富的信息。

您可以将该课程视为“拥有”图片。它最初将创建对图像的引用,因此当ResourceManager的实例被销毁时(即程序退出时)它将被处理掉它。

你的第二个例子实际上非常相似:

this.Icon = MyBrandingClass.formIcon;

您正在实现类似于ResourceManager的东西。

在这种情况下,请考虑将MyBrandingClass作为图像的所有者,因此负责将其清除。怎么样?使MyBrandingClass成为具有静态实例的单例。这样,当程序终止时,MyBrandingClass的析构函数就可以处理它在生命周期中实例化的任何资源。

您可以考虑的其他事情是让您的MyBrandingClass继承自ResourceManager。或者也许您可能只有多个ResourceManagers实例(假设您计划使用不同版本的MyBrandingClass)。正如我所说,查看Resources.Designer.cs中的文档和代码可能会让您看到实际发生的内容并提供有关可能在运行时填充ResourceManager的想法(可能来自a directory of images?)

如果在设计时知道所有资源,则另一个选项是在项目中拥有多个Resources对象。右键单击项目,添加新项,选择“资源文件”。然后,您可以使用适合每个品牌的内容填充每个品牌,并在应用程序启动时初始化对正确引用的引用。这会使您的可执行文件膨胀,因为即使您只使用一个,也包含每个品牌的所有资源。如果您想要更改品牌或添加新品牌,它还需要重建应用程序,因此可能在运行时从目录动态填充资源管理器可能会更好(尽管使安装程序包装更加复杂)。 / p>

答案 1 :(得分:1)

如果您有一个类(ResourcesMyBrandingClass),那么当这些资源超出范围时,该类应该处理其资源。

对于Resources,这不是你的工作,可能不是一个大问题,因为该类的范围应该是流程执行的持续时间。

对于MyBrandingClass,听起来你似乎也在使用它 - 静态类,它可以在你的过程中使用。如果情况并非如此,您应该妥善处理这些资源。

通常,IDisposable应该用于垃圾收集器无法自行获取的托管资源,并且应该在流程执行结束之前释放以释放资源。您的Icon资源可能是这样的资源 - 但同样,在程序执行期间也可能需要它。如果你在执行期间处理它并再次使用它,你几乎肯定会得到一个例外。

答案 2 :(得分:0)

您不会处置嵌入的资源,除非您确定不再需要它。如果品牌形式再也不会显示,那么可以处置掉。复制构造函数过度,并没有解决任何问题。

嵌入式图标不会造成太大问题。我有几百个它工作正常。一定不要保持大的阻碍。