在类中创建自己的鼠标事件

Posted

技术标签:

【中文标题】在类中创建自己的鼠标事件【英文标题】:Create your own mouse event in a class 【发布时间】:2021-10-11 21:03:18 【问题描述】:

我学习 C# 的时间不长,想知道是否可以从另一个类创建鼠标事件?

其目的是当鼠标按下时,会在面板上绘制一些东西。我想从不同的班级做这一切这可能吗?

这是我已经尝试过的:

class Circle: Form1

    Graphics g;
    Pen pen = new Pen(Color.Black);


    // Making a event ?
    public event EventHandler<MouseEventArgs> MouseDown;
    protected void OnClick(MouseEventArgs e)
    
        EventHandler<MouseEventArgs> handler = MouseDown;
        if (handler != null)
        
            handler(this, e);
        
    

    public Circle()
    
        g = this.panel1.CreateGraphics();
    
    public void Mouse_Down(object sender, MouseEventArgs e)
    
        // Draw something 
        g.DrawLine(pen, 0, 0, 50, 50);
    

因此,我不想在此类中调用 panel1_MouseDown 事件,而是想从 circle 类中调用它:

    public partial class Form1 : Form

 

    public Form1()
    
        InitializeComponent();

    

    private void panel1_MouseDown(object sender, MouseEventArgs e)
    
        // So instead of calling the panel1_MouseDown event in this class I want to call it from the circle class 
    

【问题讨论】:

为什么你认为你必须调用事件Circle 派生自 Form1,所以它是一个 Form。这是故意的,即,这是你真正想做的吗? -- 为什么要在基类中订阅MouseDown 事件? -- 顺便说一句,这是非常错误的:Graphics g; [...] g = this.panel1.CreateGraphics();:您需要使用 Panel 的 Paint 事件在其表面上绘制东西。您还应该避免使用 Panel 类来绘制,而是使用 PictureBox (本身是双缓冲的,Panel 类不是)。或从Control 派生的自定义控件(较少开销)启用双缓冲 我的意图是从circle类打开事件,但我不知道该怎么做 您确定圆是一种形式,并且圆有一个面板吗?难道你不想设计你的表单有一个画圆的面板吗? 如果圆是在面板上绘制的,那么没有理由在表格中放上绘制代码。这将使代码难以在另一种形式中重用,因为您必须重复在每种形式中绘制的代码。事实上,面板应该是一个用户控件,您可以将它放到其他地方(编译代码后从工具窗口中)。了解 DRY(不要重复自己)原则。 【参考方案1】:

是的,你可以“从不同的班级做这一切” 参考下面的例子:

    在 Form1 构造函数中,create 初始化 Circle 类的实例,并将 Form1 的实例传递给它的构造函数。 确保您要绘制的控件是公开的(示例中为panel1)。 将MouseDownPaint 事件添加到panel1。 始终使用Paint 事件绘制图形 - 这是最佳做法。 有关 Control.Paint 事件的更多信息,请:read here

Form1:

public partial class Form1 : Form

    Circle circle;
    public Form1()
    
        InitializeComponent();
        // Start the measuring time for reauthentication
        circle = new Circle(this);
    

圈子类:

class Circle

    private Form1 Instance;
    public Circle(Form1 instance)
    
        this.Instance = instance;
        // Make sure the access modifier of panel1 is Public and add mousedown event
        Instance.panel1.MouseDown += panel1_MouseDown;
        // Add a paint event - this is the best practice to draw graphics
        Instance.panel1.Paint += panel1_Paint; 
    


    private int X;
    private int Y;
    private void panel1_MouseDown(object sender, MouseEventArgs e)
    
        this.X = e.X;
        this.Y = e.Y;    
        // Redraw the panel when mouse is down
        Instance.panel1.Refresh();
    

    private void panel1_Paint(object sender, PaintEventArgs e)
    
        if (this.X > 0 && this.Y > 0)
        
            Graphics g = e.Graphics;
            Pen p = new Pen(Color.Red);
            g.DrawEllipse(p, X, Y, 50, 50);
        
    

输出:

【讨论】:

更好的设计是面板会声明像CircleMouseDown 这样的事件并挂钩它们,以便事件在放置面板的设计器中可用。此外,当您手动挂钩事件时,您应该在之后不正常地取消挂钩。 o.p 提出的问题是:“是否可以从另一个类创建鼠标事件?”

以上是关于在类中创建自己的鼠标事件的主要内容,如果未能解决你的问题,请参考以下文章

发生鼠标悬停事件时如何更改饼图的颜色

在鼠标移动中创建涂抹/液化效果,使用webgl连续动画回原始状态

鼠标滚轮增量值始终为 120

UGUI中鼠标点击进入等事件的监听

如何在输入文本区域中创建 Enter 事件以使用 Vue.js 和 Electron 按下按钮

jq之鼠标事件