我使用C#,VisualStudio 2010,我为Windows窗体应用程序创建了一个自定义UserControl。除了展示自己并允许自己被拖到其他地方之外,他们没有太多的行为。然而,它们是圆形的,当它们在角落重叠时我无法正确显示它们。
以下是我在屏幕上绘制它们的代码:
public void Circle_Paint(object sender, PaintEventArgs e)
{
var g = e.Graphics;
g.FillEllipse(brushForOuterCircle, 0, 0, Width, Height);
g.FillEllipse(brushForInnerCircle, lineWidth, lineWidth, Width - 2*lineWidth, Height - 2*lineWidth);
if(!textLocation.HasValue)
{
SizeF m = g.MeasureString(text, textFont);
textLocation = new PointF((float)((Width - m.Width)/2.0), (float)((Height - m.Height)/2.0));
}
g.DrawString(text, textFont, brushForText, textLocation.Value);
}
以下是错误显示的示例,AB圈的东南部分不显示,因为CD会覆盖该区域。
我应该如何防止这种情况,有没有办法告诉UserControl"默认情况下你是透明的;我不能画的任何部分应该保持如此" ?
答案 0 :(得分:3)
尝试:
通过覆盖
在您的用户控件上设置第一个WS_EX_COMPOSITED扩展样式protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00000020; // add this
return cp;
}
}
之后不要在背景中画任何东西
protected override void OnPaintBackground(PaintEventArgs e)
{
// leave this empty
}
最后在Paint
画出你的形状。
应该工作。
答案 1 :(得分:1)
试试这个。按照此处的建议创建TransparencyControl:Transparent images with C# WinForms
using System;
using System.Windows.Forms;
using System.Drawing;
public class TransparentControl : Control
{
private readonly Timer refresher;
private Image _image;
public TransparentControl()
{
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
BackColor = Color.Transparent;
refresher = new Timer();
refresher.Tick += TimerOnTick;
refresher.Interval = 50;
refresher.Enabled = true;
refresher.Start();
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
protected override void OnMove(EventArgs e)
{
RecreateHandle();
}
protected override void OnPaint(PaintEventArgs e)
{
if (_image != null)
{
e.Graphics.DrawImage(_image, (Width / 2) - (_image.Width / 2), (Height / 2) - (_image.Height / 2));
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
//Do not paint background
}
//Hack
public void Redraw()
{
RecreateHandle();
}
private void TimerOnTick(object source, EventArgs e)
{
RecreateHandle();
refresher.Stop();
}
public Image Image
{
get
{
return _image;
}
set
{
_image = value;
RecreateHandle();
}
}
}
答案 2 :(得分:1)
您还应该设置区域,使其忽略应该透明的区域的鼠标单击。以下面的控件为例。这是一个描绘圆圈的控件。我将Region设置为Ellipse,导致WinForms不绘制圆圈外的区域。通过设置区域,它也知道忽略区域外区域的鼠标点击。
using System;
using System.Drawing.Drawing2D;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsApplication1
{
public class RoundControl : Control
{
private readonly GraphicsPath _path;
public RoundControl()
{
_path = new GraphicsPath();
}
protected override void OnResize(EventArgs e)
{
_path.Reset();
_path.AddEllipse(ClientRectangle);
Invalidate(Region);
Region = new Region(_path);
base.OnResize(e);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_path.Dispose();
}
base.Dispose(disposing);
}
protected override void OnPaint(PaintEventArgs e)
{
using (Pen borderPen = new Pen(ForeColor, 8))
{
e.Graphics.DrawEllipse(borderPen, ClientRectangle);
}
base.OnPaint(e);
}
}
}