如何创建一个可以在程序的各个部分轻松引用和使用的资源?
我的具体问题是我有一个 NotifyIcon,我想根据程序的状态更改其图标。这是一个常见问题,但我已经困扰了很长时间。
嗯,在四处搜索并拼凑了 StackOverflow 周围的各个点之后(哎呀,我已经喜欢这个地方了),大多数问题已经过了这个阶段。不过,我确实设法找到了问题的答案。
如何创建资源:
就我而言,我想创建一个图标。无论您想要添加哪种类型的数据作为资源,这都是一个类似的过程。
如何使用资源:
太棒了,我们有了新资源,我们渴望拥有那些可爱的变化图标……我们该怎么做呢?好吧,幸运的是,C# 使这变得非常简单。
有一个名为
Properties.Resources
的静态类,可以让您访问所有资源,因此我的代码最终非常简单:
paused = !paused;
if (paused)
notifyIcon.Icon = Properties.Resources.RedIcon;
else
notifyIcon.Icon = Properties.Resources.GreenIcon;
完成!完成的!当你知道如何做时,一切都会变得简单,不是吗?
上面的内容实际上并不适合我,正如我对 Visual Studio 2010 所期望的那样。它不允许我访问 Properties.Resources,说由于权限问题无法访问。 我最终不得不更改资源属性中的持久性设置,然后我找到了如何通过 Resources.Designer.cs 文件访问它,其中它有一个自动 getter,让我可以通过 MyNamespace.Properties.Resources 访问图标.NameFromAddingTheResource。 它返回一个 Icon 类型的对象,可供使用。
以上方法效果很好。
另一种方法(我假设这里是网络)是创建您的页面。向页面添加控件。然后在设计模式下转到:工具>生成本地资源。解决方案中会自动出现一个资源文件,页面中的所有控件都映射到资源文件中。
要为其他语言创建资源,请将 4 个字符的语言附加到文件名末尾、扩展名之前(Account.aspx.en-US.resx、Account.aspx.es-ES.resx...等) ).
要检索代码隐藏中的特定条目,只需调用此方法:
GetLocalResourceObject([resource entry key/name])
。
Matthew Scharley 发布的代码存在内存泄漏:
paused = !paused;
if (paused)
notifyIcon.Icon = Properties.Resources.RedIcon;
else
notifyIcon.Icon = Properties.Resources.GreenIcon;
在替换它之前,您应该
Dispose()
notificationIcon.Icon ,因为 Properties.Resources.SOME_ICON
每次使用时都会创建一个新的 Icon
。
这可以通过以下代码在日志中观察到:
Console.WriteLine(Properties.Resources.RedIcon.GetHashCode());
Console.WriteLine(Properties.Resources.RedIcon.GetHashCode());
Console.WriteLine(Properties.Resources.RedIcon.GetHashCode());
您将在日志中看到 3 个不同的哈希代码。这意味着这些是不同的对象。
因此,简单的解决方法是:
paused = !paused;
notifyIcon.Icon?.Dispose();
notifyIcon.Icon = paused
? Properties.Resources.RedIcon;
: Properties.Resources.GreenIcon;
我之所以来到这里,是因为 Visual Studio 2022 的“资源浏览器”存在问题,这是一种全新的(且已损坏的)与资源交互的方式。如果其他人遇到同样的问题,您可以通过右键单击 .resx 文件,选择 打开方式...,然后选择 托管资源编辑器(旧版),返回经典资源视图。