Can an attribute references an embeded resource?
I'm working on an application that generates a tree structure of nodes. There are many types of nodes, each with specific behavior and properties. I want to attribute each node type with properties including a display name, description, and a 16x16 icon.
Here's the code for the custom attribute I created:
public class NodeTypeInfoAttribute : Attribute
{
public NodeTypeInfoAttribute(string displayName, string description, System.Drawing.Image icon)
: this(displayName, description)
{
this.Icon = icon;
}
public NodeTypeInfoAttribute(string displayName, string description, string iconPath):this(displayName,description)
{
String absPath;
if (System.IO.Path.IsPathRooted(iconPath))
{
absPath = iconPath;
}
else
{
string folder = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
absPath = System.IO.Path.Combine(folder, iconPath);
开发者_开发问答 }
try
{
System.Drawing.Image i = System.Drawing.Image.FromFile(absPath);
}
catch (System.IO.FileNotFoundException)
{
Icon = null;
}
}
public NodeTypeInfoAttribute(string displayName, string description)
{
this.DisplayName = displayName;
this.Description = description;
}
public string DisplayName
{
get;
private set;
}
public string Description
{
get;
private set;
}
public System.Drawing.Image Icon
{
get;
set;
}
}
Note that I have a constructor that specifies the Icon as a file path, and a constructor that specifies the icon as a System.Drawing.Image
.
So ultimately I'd like to be able to use this attribute with an embedded image resource like this.
[NodeTypeInfo("My Node","Sample Description",Properties.Resources.CustomIcon)]
public class CustomNode:Node
{
...
However, this code returns the error
An attribute argument must be a constant expression, typeof expression or
array creation` expression of an attribute parameter type
Is there some other way I can associate a Type (not an instance) of a class with an icon image?
The arguments for an attribute constructor are stored in the assembly metadata. That puts severe restrictions on what kind of argument types you can use. Anything that requires code is most definitely not supported. Which is what fails here, accessing Properties.Resources requires calling a property getter.
No great alternative here as long as you want to refer to a resource. The resource name, a string, is all I can think of. Obtain the resource object in the attribute constructor with Properties.Resources.ResourceManager.GetObject()
精彩评论