0

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

これで、マウスがコントロール上を移動するたびに、メッセージ ボックスがポップアップするはずですが、ポップアップしません。デバッグを試みましたが、イベントが呼び出されないようです。ここで何が問題なのですか

4

1 に答える 1

0

実際、あなたの Control は表示されていますが、Size は Emptyです。表示される線は、コントロールに描画された線ではなく、フォームに描画されたものであり、線が表示されていると考えた理由です。任意の方向を持つラインを作成したいとします。Rectangle線の方向と水平線がなす角度に応じて、線のを計算する必要があります (辺の 1 つは線の太さです)。それを計算できる場合はRectangle、プロパティを使用しRegionてライン コントロールを正確にフィットさせる必要がありますRectangle。のようなものyourLine.Region = new Region(calculatedRectangle);。その複雑さについては、多くの UI ライブラリがサポートしてHorizontal lineおり、Vertical 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);        
  }
}
于 2013-06-28T14:30:23.697 に答える