Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 控件未在面板上绘制_C#_.net_Winforms - Fatal编程技术网

C# 控件未在面板上绘制

C# 控件未在面板上绘制,c#,.net,winforms,C#,.net,Winforms,我正在尝试向面板添加控件。鼠标在面板上向下移动时,保存点;鼠标悬停时,保存点。但在面板鼠标上没有画任何东西。如何解决 椭圆类: class Ellipse : Control { private int x; private int y; private int width; private int height; public Ellipse(int x, int y, int width, int height) {

我正在尝试向面板添加控件。鼠标在面板上向下移动时,保存点;鼠标悬停时,保存点。但在面板鼠标上没有画任何东西。如何解决

椭圆类:

class Ellipse : Control
{    

    private int x;
    private int y;
    private int width;
    private int height;

    public Ellipse(int x, int y, int width, int height)
    {
        setY(y);
        setX(x);
        setWidth(width);
        setHeight(height);
    }

    public int getX() { return x;}
    public int getY() { return y; }
    public int getWidth() { return width; }
    public int getHeight() { return height; }
    public void setX(int newx) { x = newx; }
    public void setY(int newy) { y = newy; }
    public void setWidth(int newwidth) { width = newwidth; }
    public void setHeight(int newheight) { height = newheight; }


    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        // Call methods of the System.Drawing.Graphics object.
        // Declare and instantiate a new pen.
        System.Drawing.Pen myPen = new System.Drawing.Pen(Color.Aqua);

        // Draw an aqua rectangle in the rectangle represented by the control.
        e.Graphics.FillEllipse(Brushes.Black,x,y,width,height);
    }    
}
Form1类

private void panel_MouseDown(object sender, MouseEventArgs e)
    {
        draw = true;
        x = e.X;
        y = e.Y;
    }

private void panel_MouseUp(object sender, MouseEventArgs e)
    {
        draw = false;
        xe = e.X;
        ye = e.Y;

        Item item; 
        Enum.TryParse<Item>(menuComboBoxShape.ComboBox.SelectedValue.ToString(), out item);

        switch (item)
        {

            case Item.Pencil:
                using (Graphics g = panel.CreateGraphics())
                    using (var pen = new Pen(System.Drawing.Color.Black))     //Create the pen used to draw the line (using statement makes sure the pen is disposed)
                    {
                        g.DrawLine(pen,new Point(x, y), new Point(xe, ye));
                    }
                break;
            case Item.Rectangle:
                break;
            case Item.Ellipse:
                Ellipse el = new Ellipse(x,y,xe-x,ye-y);
                panel.Controls.Add(el);

                break;
            default:
                break;
        }
    }
private void panel\u MouseDown(对象发送器,MouseEventArgs e)
{
绘制=真;
x=e.x;
y=e.y;
}
专用空白面板\u鼠标(对象发送器,鼠标目标e)
{
绘制=假;
xe=e.X;
ye=e.Y;
项目;
TryParse(menucomboxShape.ComboBox.SelectedValue.ToString(),out项);
开关(项目)
{
箱子项目。铅笔:
使用(Graphics g=panel.CreateGraphics())
使用(var pen=new pen(System.Drawing.Color.Black))//创建用于绘制线条的笔(使用语句确保笔已被释放)
{
g、 抽绳(钢笔,新点(x,y),新点(xe,ye));
}
打破
案例项。矩形:
打破
案例项目.椭圆:
椭圆el=新椭圆(x,y,xe-x,ye-y);
面板。控件。添加(el);
打破
违约:
打破
}
}

您从控件继承了
Ellipse
类,但实际上您并没有将其用作控件-您并没有将其添加到表单的
控件集合中,所以实际上它是不可见的、非活动的,并且没有从表单接收任何事件

另外,从外部代码绘制控件看起来是一个糟糕的设计。控件应该绘制自身,并且应该从外部代码设置它的边界

下面是一段代码,它将引导您找到正确的方法:

class Ellipse : Control
{
    Point mDown { get; set; }

    public Ellipse()
    {
        MouseDown += shape_MouseDown;
        MouseMove += shape_MouseMove;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.FillEllipse(Brushes.Black, this.Bounds);
    }

    private void shape_MouseDown(object sender, MouseEventArgs e)
    {
        mDown = e.Location;
    }

    private void shape_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            Location = new Point(e.X + Left - mDown.X, e.Y + Top - mDown.Y);
        }
    }
}
在表格中,您应该像这样创建它:

el = new Ellipse();
el.Bounds = new Rectangle(0, 0, 100, 100);
Controls.Add(el);
更新

根据您更新的代码,我可以看到几个问题:

  • 实际上,您不需要
    x,y,width,height
    类和相应的getter/setter方法的
    properties,因为它是
    控件
    ,并且它有自己的
    位置
    宽度
    高度
    公共属性

  • 您绘制的椭圆不正确。假设它应该填充所有区域,那么绘画应该是
    e.Graphics.FillEllipse(画笔.黑色,0,0,宽度,高度)
    (这里我假设使用
    Control.Width
    ,而不是
    Width
    等等)。否则,您将额外移动绘制的椭圆

  • 关于椭圆创建的面板\u MouseUp中的代码应该类似


  • 或者,如果它应该是一个椭圆(现在您每次都在创建一个新椭圆)-在mouseUp处理程序外部创建这个椭圆,在处理程序内部只需更改它的大小和位置。

    您尝试过调试吗?在
    mouseDown
    event上mDown的值是多少?我在
    mDown=e.Location上放置了一个断点但还没到面板是什么?您可以共享相关代码吗?窗体上的
    KeyPreview
    属性是否设置为
    true
    ?您需要将控件添加到面板中,而不仅仅是手动将其覆盖。只需执行例如
    panel.Controls.Add(new Ellipse())
    。当你在任何地方都没有控件时,鼠标事件怎么会触发?就用户界面而言,它们并不存在。你只是在调用一个
    Paint
    方法,就这样。我明白你的意思,但是我的
    Shape
    类应该是什么样子?@Sybren我在你的
    Shape
    类中看到的就是
    Paint
    方法。如果我们遵循“控件应该自己绘制,而不是从外部代码绘制”的概念,那么就不需要这种方法。如果你需要更多的形状-这取决于你。如果没有更多的形状-可能根本不需要它,您可以直接从
    控件继承椭圆进入该
    面板。控件。添加(el)因为我想添加到
    面板
    。这是结果:。有什么想法吗?@Sybren如果不看到你改变代码,很难说很多。我希望您没有“盲目地”复制我的代码,因为它是一些抽象片段(例如,它固定了矩形以绘制椭圆等等)。另请注意-您需要在
    面板\u MouseUp
    外部创建椭圆,并且在MouseUp处理程序中,您应该只更新其位置(如果我正确理解了您试图执行的操作)。我想在MouseUp处绘制,请查看修改后的代码。
    var el = new Ellipse();
    panel.Controls.Add(el);
    el.Location = new Point(x, y);
    el.Width = (xe - x);
    el.Height = (ye - y);