Winforms和资源(Resources/resx)
http://www.sellsbrothers.com/writing/ResourcesAndWinForms.htm
资源(A resource)是在Build期间被绑定在程序集里的命名数据。例如,你可以在你的应用程序中是用如下方式,通过载入文件系统中的图片,来设置背景图片:
public MainForm() {
InitializeComponent();
this.BackgroundImage = new Bitmap(@"C:\WINDOWS\Web\Wallpaper\Azul.jpg");
}
这段代码的问题当然是,不是所有的用户的Windows中都有Azul.jpg,而那些即使有的也很可能不在同一位置。即使你把图片放到你的应用程序中,一个很在意空间的用户很可能决定移出它,导致你的应用程序出现故障(这个原因好像有些扯,敢硬删应用程序文件夹内容的用户自然必须承受这个代价,虽然以前这种事情我也干过。。。)。唯一保险的方式就是确保把图片,或其他文件作为一个资源文件嵌入。你可以使用两种方式来实现。一种方式是在你的项目的Solution Explorer中右键点击,添加一个存在的项目,然后选中你想要嵌入的文件。这个文件就会被复制到你的项目的文件夹,但依然不会被嵌入。要作为资源嵌入项目,你需要右键点击文件,选择属性,在属性中找到“Embedded Resource”的选项。这样做完了之后就能够在运行时载入这个文件。很多.NET类提供了使用资源标识的构造函数,例如Bitmap:
public MainForm() {
InitializeComponent();
this.BackgroundImage = new Bitmap(this.GetType(), "Azul.jpg");
}
当作为一个资源被嵌入后,资源的完整名称会由项目的默认命名空间与文件名组成,例如MySecondApp.Azul.jpg。当图片在运行时被载入时,第一个参数是那个资源的类型,然后是名字的字符串。
当然,如果你直接地想在设计器看到作为背景的效果,你可以使用Property Browswer,而完全不用写载入资源的代码。例如对于背景图片,就是BackgroundImage property。这样设计器就会自动生成代码:
namespace MySecondApp {
public class MainForm : System.Windows.Forms.Form {
public MainForm() {
InitializeComponent();
}
private void InitializeComponent() {
System.Resources.ResourceManager resources =
new System.Resources.ResourceManager(typeof(MainForm));
...
this.BackgroundImage =
(Bitmap)resources.GetObject("$this.BackgroundImage");
...
}
...
}
在这个例子中,不是直接使用了Bitmap构造函数,而是使用了ResourceManager类。这个类可以在运行时直接访问区域性特定资源,不管资源是不是在程序集中。这样Form部署的世后就不需要改动代码或重新编译了。
另外project的Properties下默认有一个Resources.resx Resource文件。WinForm窗体默认有一个resx文件跟随。resx文件是个resource文件,即程序资源文件。
调用的时候可以这样调用:
this.BackgroundImage = global::NamespaceName.Properties.Resources.resourcename;