我有一个奇怪的问题。我自己创建了来自UserControl
的用户控件。我重写了OnPaint
。现在我在OnPaint
画一些东西。让我们说在0,0位置。
如果我在自定义绘图后调用base.OnPaint
,一切都很好。但是如果我在绘制的东西之前调用base.OnPaint
,它似乎忽略了包含控件,并且位置相对于窗体而不是相对于父控件的客户区域。因此,当我在位置(0,0)处绘制时,它将有效地绘制在负x和y处,而我只会看到它的一部分。 base.OnPaint
为UserControl.OnPaint
。所以我不会在那里调用我的代码。
以下是一个例子:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var rect = new System.Drawing.Rectangle(this.ClientSize.Width - 16,
this.ClientSize.Height - 16, 16, 16);
e.Graphics.FillRectangle(new System.Drawing.SolidBrush(System.Drawing.Color.Red), rect);
//base.OnPaint(e);
}
在这种情况下,红色矩形显示在客户区内的某处,但不显示在右下角。如果我取消注释最后一行并注释第一行,红色矩形将按预期显示在右下角。
我不明白。我做了很多次这总是有效的。所以我试图发现任何差异。我唯一发现的是我没有在设计器中添加我的控件,而是以编程方式将其添加到theContainingControl.Controls.Add(myMessedUpControl);
的另一个控件中。
这也适用于我添加的每个父子级别。因此,如果我创建另一个控件(另一个类)并覆盖OnPaint
,如果我将其添加到另一个用户控件,行为是相同的。
之前有没有人有这种行为?我怎样才能解决这个问题?问题是,我想首先致电base.OnPaint
并且每个人都建议这样做。但正如我所说,我不能没有弄乱坐标。
一个注意事项:在DrawLine
,DrawImage
或DrawString
之类的绘制调用中,调试器中的坐标实际为0,0。但结果显示在负坐标(相对于客户区)。看起来客户端坐标被解释为表单的客户端坐标。但我不知道为什么。
发现问题
在我的项目中有一个图形覆盖类,它将Paint
事件处理程序连接到我的表单中的所有控件(整个层次结构)。在此处理程序中,执行转换。这种图形叠加让我多次失眠。我想我会删除它。
答案 0 :(得分:1)
Graphics
对象有很多可变状态。如果你搞乱这种可变状态,操作顺序就很重要 - 例如,你可以使用Transform
矩阵来改变表面上渲染的所有东西的偏移量。
听起来你的上升者在其自己的OnPaint
处理程序中更改其中一个而不重置它。在开始绘画之前尝试做e.Graphics.ResetTransform();
。确保所有其他状态也是您想要的状态(剪辑,DPI,......)。