在表单上绘制自定义图标
我正在 C# winforms 中创建自定义控件。我已经向资源添加了一个图标,然后使用下面的代码将该图标绘制到控件上:
using (Icon oIcon = Properties.Resources.DropDownCustom)
{
Rectangle RectangleIcon = new Rectangle((DropDownRectangle.X + ((DropDownRectangle.Width / 2) - (oIcon.Width / 2))),
(DropDownRectangle.Y + (((DropDownRectangle.Height / 2) - (oIcon.Height / 2)) + 1)),
oIcon.Width,
oIcon.Height);
graphics.DrawIcon(oIcon, RectangleIcon);
}
这一切都工作正常,没有问题,但后来我决定向控件属性添加一个选项,以允许开发人员加载自己的要使用的图标,而不是使用我放置在资源中的图标。我创建了一个私有 Icon 变量:
private Icon _DropDownCustom;
将上面代码中的“using”行更改为:
using (Icon oIcon = _DropDownCustom)
,然后将以下行添加到构造函数中,以将默认值设置为资源中的值。
_DropDownCustom = Properties.Resources.DropDownCustom;
然后,我添加了一个 Icon 属性,以便开发人员可以使用他们自己的图标:
[Category("Appearance"), DisplayName("IconDropDown")]
public Icon IconDropDownCustom
{
get { return _DropDownCustom; }
set { _DropDownCustom = value; this.Invalidate(); }
}
所有这一切似乎都工作正常,但现在,当我在表单上查看控件(在开发模式下)时,它会将图标绘制到控件上 - 太棒了,但是一旦我选择表单或控件,图标就会消失,但其他绘画仍然存在(即分级背景)。
有谁知道为什么它似乎没有重新绘制图标?
非常感谢。
编辑: 我刚刚删除了代码的“Using(){}
”部分并将其更改为:
Icon oIcon = _DropDownCustom;
Rectangle RectangleIcon = new Rectangle((DropDownRectangle.X + ((DropDownRectangle.Width / 2) - (oIcon.Width / 2))),
(DropDownRectangle.Y + (((DropDownRectangle.Height / 2) - (oIcon.Height / 2)) + 1)),
oIcon.Width,
oIcon.Height);
graphics.DrawIcon(oIcon, RectangleIcon);
这似乎按预期工作,所以我猜测这与使用和处置有关 - 仍然试图理解爆炸部分 - 你能解释一下为什么会发生这种情况吗?我猜我的“oIcon”基本上只是引用我的自定义图标变量而不是“按值”(我来自 VB 背景)。
I'm creating a custom control in C# winforms. I've added an ICON to the resource, this icon is then drawn onto the control using the code below:
using (Icon oIcon = Properties.Resources.DropDownCustom)
{
Rectangle RectangleIcon = new Rectangle((DropDownRectangle.X + ((DropDownRectangle.Width / 2) - (oIcon.Width / 2))),
(DropDownRectangle.Y + (((DropDownRectangle.Height / 2) - (oIcon.Height / 2)) + 1)),
oIcon.Width,
oIcon.Height);
graphics.DrawIcon(oIcon, RectangleIcon);
}
This all works fine no problem, but then I decided to add an option to the control properties to allow the developer to load their own icon to use rather than use the one I've placed in the resource. I created a private Icon variable:
private Icon _DropDownCustom;
changed the "using" line in the above code to read:
using (Icon oIcon = _DropDownCustom)
and then added to the constructor the following line to set the default value to the one in the resources.
_DropDownCustom = Properties.Resources.DropDownCustom;
I've then added an Icon property so the developer can use thier own icon:
[Category("Appearance"), DisplayName("IconDropDown")]
public Icon IconDropDownCustom
{
get { return _DropDownCustom; }
set { _DropDownCustom = value; this.Invalidate(); }
}
All this seems to be working fine, except now, when I view the control on a form (in development mode) it paints the icon onto the control - great, but as soon as I select the form, or the control the Icon disappears, but other painting stays (ie grading background).
Does anyone know why it doesn't seem to repaint the icon?
Many thanks.
EDIT:
I've just removed the "Using(){}
" part of the code and changed it to:
Icon oIcon = _DropDownCustom;
Rectangle RectangleIcon = new Rectangle((DropDownRectangle.X + ((DropDownRectangle.Width / 2) - (oIcon.Width / 2))),
(DropDownRectangle.Y + (((DropDownRectangle.Height / 2) - (oIcon.Height / 2)) + 1)),
oIcon.Width,
oIcon.Height);
graphics.DrawIcon(oIcon, RectangleIcon);
This seems to work as expected so I'm guessing it's something to do with using and disposing - Still trying to understand the displosing part - could you please explain why this is happening? I'm guessing my "oIcon" is basically just referencing my custom Icon variable rather than "by value" (I'm from a VB background).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Icon 资源周围的“using”块将向 GC 发出信号,表明不再需要该位置的内存,并将对其进行清理。因此,在第一次绘制后,图标将不再有效(除非您每次绘制它时都加载并处理它)。
您可能应该:
处理控件的关闭事件并处置那里的资源。
在用户控件上实现一次性模式来清理资源(例如当不再需要您的控件时,您的图标)。
The "using" block around your Icon resource will signal to the GC that the memory at that location is no longer needed and it will clean it up. So, after the first time it gets drawn the Icon will no longer be valid (unless you load it and dispose it every time you draw it).
You should probably either:
Handle the close event of the control and dispose of the resources there.
Implement the Disposable pattern on your user control to clean up resources (like your Icon) when your control is no longer needed.