c# - 自定义光标异常?

标签 c# image winforms cursor panel

我在使用 Windows 窗体在 C# 中使用自定义游标时遇到了一些奇怪的行为。我已将问题减少到一个新项目,其中包含 1 个表单、2 个面板添加到表单、1 个图标添加到项目的 properties/resources.resx,以及 3 个图像添加到同一个地方。

项目唯一的代码就是这个

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TestProject
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            panel1.Cursor = new Cursor(Properties.Resources.randomIcon.Handle);
            panel2.Cursor = new Cursor(Properties.Resources.randomIcon.Handle);
        }
    }
}

现在,当我修改 Form 的 backgroundimage 属性时,奇怪的行为开始了。我从各种来源下载了多个随机图像并将它们设置为表单的背景图像。

  • 当我设置其中一些并运行程序时,两个面板都有自己的自定义光标。

  • 当我设置其他图像时,只有第二个面板有光标。

  • 我什至找到了一张图片,其中 panel1 在前几秒有光标,但如果我碰巧在那几秒后离开并返回面板,光标将被永久删除。

如果我将表单的 backgroundimagelayout 属性更改为 None 而不是 Tile,则无论图像是什么,光标都会起作用。

整个项目中没有任何其他内容需要修改。 1 个表格、2 个面板、1 个作为光标的图标、3 张图像和完全没有意义的(或者可能没有,也许我遗漏了什么)行为。

我只是想找出导致这种行为的原因,因为我在处理更大的项目时遇到了这种情况,我花了一些时间来追踪问题的核心。也许我不应该以这种方式使用游标,但问题仍然存在,是什么让 c# 在仅修改背景图像时以这种方式运行。

我在这里做了一个示例项目 - https://www.dropbox.com/s/bl4iomzyz1bv7kb/Sample.rar?dl=0

最佳答案

来自您使用的 Icon.Handle 属性的 MSDN 文章:

This is not a copy of the handle; do not free it.

委婉地说,这比实际情况更隐秘。它的意思是 Handle 仅在 Icon 对象未被销毁时才有效。这是您的代码中的一个问题,您没有确保 Properties.Resources.randomIcon 返回的 new 对象在任何地方都被引用。

所以垃圾收集器一运行,图标对象就成为历史。句柄不再有效。这反过来又使游标无效。图像的唯一相关性是它们对 GC 的影响。

你必须这样写:

    private Icon customCursor;

    public Form1()
    {
        InitializeComponent();
        customCursor = Properties.Resources.Cat;
        panel1.Cursor = panel2.Cursor = new Cursor(customCursor.Handle);
    }

现在,只要表单对象保持事件状态,垃圾收集器就会始终看到对 Icon 对象的引用。所以它的 Handle 属性保持有效。

这也有勋章的另一面。 Icon 类实现 IDisposable。所以成为一个优秀的 .NET 公民:

    protected override void OnFormClosed(FormClosedEventArgs e) {
        customCursor.Dispose();
        base.OnFormClosed(e);
    }

Fwiw,可以很安全地假设,如果 Microsoft 可以重新设计 .NET 1.0 图标和 Cursor 类,以及 Properties.Resources 工具,他们可能会采用不同的方式:)

关于c# - 自定义光标异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33488483/

相关文章:

android - 使用通用图像加载器保存本地恢复的图像

c# - Winforms 应用程序的报告生成器选项?

c# - 如何更改 Windows 窗体应用程序的标题图标

c# - 关闭 WinForm 应用程序时一次性对象的生命周期

c# - SQLite 标量函数返回类型始终为字符串?

c# - .NET 3.5 的 Lazy<T> 实现

css - asp.net 图像(不在图像文件夹中)被嵌入样式隐藏

c# - ASP.NET 网页跳过代码隐藏中的程序集函数调用

c# - 超时异常导致SqlDataReader关闭?

php - 如何使用表格数据添加图像