简体   繁体   English

自定义控件继承的事件未触发

[英]Custom Control Inherited event not firing Up

I have a user control which inherits from Control and is drawn by myself using Graphics Object. 我有一个用户控件,它继承自Control ,由我自己使用Graphics Object绘制。

public class Line : Control
{
    public Point start { get; set; }
    public Point end { get; set; }
    public Pen pen = new Pen(Color.Red);
}

This is main Form 这是主要形式

public partial class Form1 : Form
{
    public Line line = new Line() { start = new Point(50, 50), end = new Point(100, 100) };
    public Form1()
    {
        InitializeComponent();
        Controls.Add(line);
        line.MouseEnter += new EventHandler(line_MouseEnter);
    }

    void line_MouseEnter(object sender, EventArgs e)
    {
        MessageBox.Show("Hello World");
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        using (Graphics g = this.CreateGraphics())
        {
            g.DrawLine(line.pen, line.start, line.end);
        }
    }
}

Now whenever the mouse rolls over the control the message box should pop up, but it doesn't. 现在,每当鼠标悬停在控件上时,都会弹出消息框,但不会弹出。 I have tried debugging and it seems that the event is never getting invoked. 我已尝试调试,但似乎从未调用过该事件。 What's wrong here 怎么了

In fact your Control is visible but has Size of Empty . 实际上,您的控件是可见的,但具有“空”的大小 The line you see is not the line drawn on your Control, it's drawn on your form and that's why you thought your line is visible. 您看到的线不是在控件上绘制的线,而是在窗体上绘制的,这就是为什么您认为线可见的原因。 You want to create your line which has an arbitrary direction. 您要创建具有任意方向的线。 I think that's a little hard to do, you have to calculate the Rectangle of your line (one of the sides is your line thickness) depending on the angle made by your line direction and the horizontal line. 我认为这有点困难,您必须根据线方向和水平线所成的角度来计算线的Rectangle (边之一是线的粗细)。 If you can calculate that Rectangle , you have to use the Region property to make your line control exactly fit its Rectangle . 如果可以计算该Rectangle ,则必须使用Region属性使您的线控件完全适合其Rectangle Something like yourLine.Region = new Region(calculatedRectangle); 类似于yourLine.Region = new Region(calculatedRectangle); . For that complexity , many UI library just supports Horizontal line and Vertical line because we can calculate their Rectangle easily and they are used more frequently than other kind of lines. 由于这种复杂性,许多UI库仅支持Horizontal lineVertical line因为我们可以轻松地计算其Rectangle并且它们比其他类型的线使用得更频繁。 Here is the code for a Horizontal line, I don't have time to dig into coding a full-feature line as you want, but you may want to try yourself: 这是一条水平线的代码,我没有时间去研究编码全功能线,但是您可能想尝试一下:

public class Line : Control
{    
  Color lineColor = Color.Red;
  public Color LineColor {
      get { return lineColor;}
      set {
          lineColor = value;
          BackColor = value;
      }
  }
  public Line(){
     Height = 1;//Default thickness
     Width = 100;//Default length
     BackColor = lineColor;
  }
  //for the case you want to draw yourself, add code in this method
  protected override void OnPaint(PaintEventArgs e){
       base.OnPaint(e);
       //your code
  }
}
//use it
Line line = new Line(){Left = 50, Top = 50};
line.MouseEnter += new EventHandler(line_MouseEnter);

If you want to draw the line on your form, I think your line is in fact a structure storing information of a line (thickness, length, start point, end point). 如果您想在表单上画线,我想您的线实际上是一种存储线信息(厚度,长度,起点,终点)的结构。 So you don't need it to inherit Control , and to register MouseEnter , you have to add MouseMove event handler for your form, not your line. 因此,您不需要它继承Control并注册MouseEnter ,而不必为表单(而不是您的行)添加MouseMove事件处理程序。 However your line Rectangle will help. 但是您的Rectangle线会有所帮助。 Again, you still have to calculate your line Rectangle , which is not easy as I said before. 同样,您仍然需要计算Rectangle线,就像我之前说的那样,这并不容易。 To demonstrate it, I just calculate the Rectangle of your line in a simple way (increase X of both start and end point by 1): 为了说明这一点,我只是以一种简单的方式计算直线的Rectangle (将起点和终点的X都增加1):

//Your control has Size of Empty in this example, it just stores information of your line and is used to register the MouseMove event handler with the Form when its Parent is changed (to Form).
public class Line : Control
{
  public Point start { get; set; }
  public Point end { get; set; }
  public Pen pen = new Pen(Color.Red);
  protected override void OnParentChanged(EventArgs e){
    if(Parent != null){
        Parent.MouseMove -= MouseMoveParent;
        Parent.MouseMove += MouseMoveParent;
    }
  }
  private void MouseMoveParent(object sender, MouseEventArgs e){
     //the line Rectangle is specified by 4 points
     //I said that this is just for demonstrative purpose because to calculate
     //the exact 4 points (of the line Rectangle), you have to add much more code.
     Point p1 = start;
     Point p2 = new Point(p1.X + 1, p1.Y);
     Point p3 = new Point(end.X + 1, end.Y);
     Point p4 = end;
     System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();
     gp.AddPolygon(new Point[]{p1,p2,p3,p4});
     Region lineRegion = new Region(gp);
     if(lineRegion.IsVisible(e.Location)){
         MessageBox.Show("Hello World");
     }
  }
}
public partial class Form1 : Form
{
  public Line line = new Line() { start = new Point(50, 50), end = new Point(100, 100) };
  public Form1()
  {
    InitializeComponent();
    Controls.Add(line);
  }     
  private void Form1_Paint(object sender, PaintEventArgs e)
  {        
    e.Graphics.DrawLine(line.pen, line.start, line.end);        
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM