【问题标题】: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(不要重复自己)原则。

标签: c# winforms events


【解决方案1】:

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

  1. 在 Form1 构造函数中,create 初始化 Circle 类的实例,并将 Form1 的实例传递给它的构造函数。
  2. 确保您要绘制的控件是公开的(示例中为panel1)。
  3. MouseDownPaint 事件添加到panel1
  4. 始终使用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 提出的问题是:“是否可以从另一个类创建鼠标事件?”
猜你喜欢
  • 1970-01-01
  • 2010-10-12
  • 1970-01-01
  • 2012-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-28
相关资源
最近更新 更多