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