自定义控件继承事件未启动

时间:2013-06-28 13:02:29

标签: c# .net winforms gdi+

我有一个继承自Control的用户控件,由我自己使用Graphics Object绘制。

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

这是主要表格

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);
        }
    }
}

现在,只要鼠标滚过控件,就会弹出消息框,但事实并非如此。我已经尝试过调试,似乎永远不会调用该事件。这里有什么不对

1 个答案:

答案 0 :(得分:0)

实际上您的控件是可见的,但大小为空。您看到的线不是您的控件上绘制的线,它是在您的表单上绘制的,这就是您认为您的线条可见的原因。您想要创建具有任意方向的线。我认为这有点难,你必须根据线方向和水平线的角度计算线的Rectangle(其中一条边是线条粗细)。如果您可以计算Rectangle,则必须使用Region属性使您的线控完全符合其Rectangle。像yourLine.Region = new Region(calculatedRectangle);这样的东西。对于这种复杂性,许多UI库只支持Horizontal lineVertical line,因为我们可以轻松地计算它们的Rectangle,并且它们比其他类型的线更频繁地使用。以下是水平线的代码,我没有时间深入研究全功能线的编码,但您可能想尝试自己:

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);

如果您想在表单上绘制线条,我认为您的线条实际上是一个存储线条信息(厚度,长度,起点,终点)的结构。因此,您不需要继承Control,并注册MouseEnter,您必须为表单添加MouseMove事件处理程序,而不是您的行。但是,您的行Rectangle会有所帮助。同样,你仍然需要计算你的行Rectangle,这不像我之前说的那么容易。为了演示它,我只是以一种简单的方式计算你的行的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);        
  }
}