如何在 C# 中为插件创建 Icon 属性?
我已经根据常见做法创建了自己的插件架构,但我仍坚持使用图标。
首先,我的插件定义了主机使用的客户端,每个客户端都定义了如下属性:
[Client("Heroes of Newerth", "Heroes of Newerth Chat Client", "hon_16.png")]
有了这个,我的主机应用程序可以读取插件/客户端的元信息,而无需实际创建它的实例,但我坚持使用图标部分。
如上面的示例所示,客户端可以传递位图文件名,在我的属性实现中,我可以这样处理它:
[AttributeUsage(AttributeTargets.Class)]
public class ClientAttribute : Attribute
{
private string _name;
private string _description;
private Bitmap _icon;
public string Name { get { return this._name; } }
public string Description { get { return this._description; } }
public Bitmap Icon { get { return this._icon; } }
public ClientAttribute(string Name, string Description, string IconFile = null)
{
this._name = Name;
this._description = Description;
this._icon = new Bitmap(IconFile);
}
}
问题是,在这个方法中,我需要按原样发布我的版本的图标文件,并且无法添加它们到资源。我很高兴听到一种仍然可以将图标嵌入到资源中的方法。
I’ve created my own plugin architecture based on the common practices but I’m stuck with icons.
First of all my plugins define Clients to be used by the host and each Client is defined with attributes like:
[Client("Heroes of Newerth", "Heroes of Newerth Chat Client", "hon_16.png")]
With this my host application can read the plugin/client's metainfo without actually creating an instance of it but I’m stuck with the icon part.
As in the above example a client can pass a bitmap file name and in my attributes implementation I can handle it like this:
[AttributeUsage(AttributeTargets.Class)]
public class ClientAttribute : Attribute
{
private string _name;
private string _description;
private Bitmap _icon;
public string Name { get { return this._name; } }
public string Description { get { return this._description; } }
public Bitmap Icon { get { return this._icon; } }
public ClientAttribute(string Name, string Description, string IconFile = null)
{
this._name = Name;
this._description = Description;
this._icon = new Bitmap(IconFile);
}
}
The problem is that within this method I need to publish the icon files with my release as is and can't add them to resources. I'll be happy to hear a method that I can still embed the icons in resources.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以将它们添加到资源中,然后从自定义属性访问资源。但是,您需要对插件程序集的引用,因此无法在构造函数中执行此操作。我会这样做:
当然,这意味着当您第一次检索自定义属性时,
Icon
属性将返回 null,直到您使用正确的程序集调用Resolve
为止。我已经编写了它,以便在出现问题时它保持为空;您需要决定是否要抛出异常。特别是,当_icon
为 null 但_resourceName
不是 null 时,Icon
属性 getter 可能应该抛出异常,因为这意味着>Resolve
未调用,或者存在问题。 (您仍然应该注意,即使Resolve
也可能会抛出异常,因为GetManifestResourceStream
或Bitmap
构造函数可能会抛出异常。)You can add them to the resources, and then access the resources from the custom attribute. However, you need a reference to the plugin’s assembly, so you can’t do it in the constructor. I would do it like this:
Of course, this means that when you first retrieve the custom attribute, the
Icon
property will return null until you callResolve
with the correct assembly. I’ve written it so that it stays null if there are problems; you need to decide whether you want to throw exceptions instead. In particular, maybe theIcon
property getter should throw an exception when_icon
is null but_resourceName
isn’t, because then it means thatResolve
wasn’t called, or there was a problem. (You should still be aware that evenResolve
can throw becauseGetManifestResourceStream
or theBitmap
constructor might throw.)为什么不呢?您可以将
IconFile
定义为与插件位于同一程序集中的资源名称。然后,给定包含插件的Assembly
,调用assembly.GetManifestResourceStream
并将该流传递给Bitmap
构造函数。Why not? You could define
IconFile
as the name of a resource within the same assembly as the plugin. Then, given anAssembly
that contains the plugin, callassembly.GetManifestResourceStream
and pass that stream to theBitmap
constructor.感谢 timwi 这是我的最终实现;
在我的 PluginInfo 类中,我调用解析器;
Thanks to timwi here's my final implementation;
And in my PluginInfo class i call the resolver;