我创建了一个自定义控件来绘制一个Dial型仪表,但是遇到了一个奇怪的问题。我正在使用压力表的形式有两个这样的压力表。一个量规可以很好地工作(一个量规停在左侧),但即使在Visual Studio中,右侧的量规也无法显示。
如果我在Visual Studio中,并且从“代码”选项卡更改为带有量规的选项卡,则永远不会绘制一个量规,并且它仍显示上一个选项卡中的文本。如果我单击量规,则量规会突然绘制。
在程序也运行时会发生这种情况,而不是重新绘制空间,它只是完全透明的,甚至擦除了表单背景。
OnPaint代码如下:
protected override void OnPaint(PaintEventArgs e)
{
int size = ClientSize.Height - GaugeThickness;
float x = (GaugeThickness / 2) + OffsetX;
float y = (GaugeThickness / 2) + OffsetY;
if (this.HorizontalAlignment == HorizontalAlignment.Left)
{
x = ((size / 2) * -1) + OffsetX;
}
else if (this.HorizontalAlignment == HorizontalAlignment.Right)
{
x = (size / 2) + OffsetX;
}
if (this.VerticalAlignment == VerticalAlignment.Top)
{
y = ((size / 2) * -1) + OffsetY;
}
else if (this.VerticalAlignment == VerticalAlignment.Bottom)
{
y = (size / 2) + OffsetY;
}
PaintBackground(e, x, y);
PaintText(e, x, y, size, size);
PaintMarks(e, x, y);
PaintNeedle(e, x, y);
}
protected virtual void PaintBackground(PaintEventArgs e, float x, float y)
{
int size = ClientSize.Height - GaugeThickness;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
//Draw background
using (Pen p = new Pen(GaugeColor, GaugeThickness))
{
e.Graphics.DrawArc(p, x, y, size, size, StartAngle, SweepAngle);
}
}
protected virtual void PaintText(PaintEventArgs e, float x, float y, int width, int height)
{
TextFormatFlags horizontal = TextFormatFlags.HorizontalCenter;
TextFormatFlags vertical = TextFormatFlags.VerticalCenter;
if (this.TextAlignmentHorizontal == HorizontalAlignment.Left)
{
horizontal = TextFormatFlags.Left;
}
else if (this.TextAlignmentHorizontal == HorizontalAlignment.Right)
{
horizontal = TextFormatFlags.Right;
}
if (this.TextAlignmentVertical == VerticalAlignment.Top)
{
vertical = TextFormatFlags.Top;
}
else if (this.TextAlignmentVertical == VerticalAlignment.Bottom)
{
vertical = TextFormatFlags.Bottom;
}
Rectangle rect = new Rectangle((int)x, (int)y, width, height);
e.Graphics.FillEllipse(new SolidBrush(Color.Transparent), rect);
TextRenderer.DrawText(e.Graphics, this.Text, this.Font, rect,
this.ForeColor, horizontal | vertical);
}
protected virtual void PaintMarks(PaintEventArgs e, float x, float y)
{
int size = ClientSize.Height - GaugeThickness;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
//Draw Marks
float markLocation = 0.0f;
float spacing = SweepAngle / 10;
for (int i = 0; i < 11; i++)
{
using (Pen p = new Pen(MarkColor, MarkLength))
{
p.Alignment = PenAlignment.Inset;
e.Graphics.DrawArc(p, x, y, size, size, markLocation + StartAngle, MarkThickness);
markLocation += spacing;
}
}
}
protected virtual void PaintNeedle(PaintEventArgs e, float x, float y)
{
int size = ClientSize.Height - GaugeThickness;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
//Draw needle.
if (Value >= MaxValue) Value = MaxValue;
using (Pen p = new Pen(NeedleColor, NeedleLength))
{
p.Alignment = PenAlignment.Inset;
e.Graphics.DrawArc(p, x, y, size, size, StartAngle + GetNeedleAngle(), NeedleSweep);
}
base.OnPaint(e);
}
我真的不知道有什么线索导致整个控件在单击之前完全无法绘制。
我已经检查了Display.Designer.CS,并且两个控件都添加到了“ Display.Controls”中。
有人看到我不知道的东西吗?
我运行了Debug,实际上直到GPU标尺失去/获得焦点后,OnPaint函数才真正在GPU标尺上被调用。
这是我整个DialGauge课:
public class DialGauge : Control
{
#region Properties
[Browsable(true)]
public float StartAngle { get => _startAngle; set { _startAngle = value; Invalidate(); } }
[Browsable(true)]
public float SweepAngle { get => _sweepAngle; set { _sweepAngle = value; Invalidate(); } }
[Browsable(true)]
[DefaultValue(100d)]
public double MaxValue { get => _maxvalue; set { _maxvalue = value; Invalidate(); } }
[Browsable(true)]
public int GaugeThickness { get => _gaugethickness; set { _gaugethickness = value; Invalidate(); } }
[Browsable(true)]
[DefaultValue(150)]
public int NeedleLength { get => _needlelength; set { _needlelength = value; Invalidate(); } }
[Browsable(true)]
[DefaultValue(5)]
public float NeedleSweep { get => _needlesweep; set { _needlesweep = value; Invalidate(); } }
[Browsable(true)]
[DefaultValue(0.0)]
public double Value { get => _value; set { _value = value; Invalidate(); } }
[Browsable(true)]
public Color GaugeColor { get => gaugecolor; set { gaugecolor = value; Invalidate(); } }
[Browsable(true)]
public Color NeedleColor { get => needlecolor; set { needlecolor = value; Invalidate(); } }
[Browsable(true)]
public float MarkLength { get => _marklength; set { _marklength = value; Invalidate(); } }
[Browsable(true)]
public Color MarkColor { get => _markcolor; set { _markcolor = value; Invalidate(); } }
[Browsable(true)]
public float MarkThickness { get => _markthickness; set { _markthickness = value; Invalidate(); } }
[Browsable(true)]
[DefaultValue(HorizontalAlignment.Center)]
public HorizontalAlignment HorizontalAlignment { get => _horizontalalignment; set { _horizontalalignment = value; Invalidate(); } }
[Browsable(true)]
[DefaultValue(VerticalAlignment.Center)]
public VerticalAlignment VerticalAlignment { get => _verticalalignment; set { _verticalalignment = value; Invalidate(); } }
[Browsable(true)]
[DefaultValue(0f)]
public float OffsetX { get => _offset_x; set { _offset_x = value; Invalidate(); } }
[Browsable(true)]
[DefaultValue(0f)]
public float OffsetY { get => _offset_y; set { _offset_y = value; Invalidate(); } }
[Browsable(true)]
[DefaultValue(HorizontalAlignment.Center)]
public HorizontalAlignment TextAlignmentHorizontal { get => _texthorizontalalignment; set { _texthorizontalalignment = value; Invalidate(); } }
[Browsable(true)]
[DefaultValue(VerticalAlignment.Center)]
public VerticalAlignment TextAlignmentVertical { get => _textverticalalignment; set { _textverticalalignment = value; Invalidate(); } }
[Browsable(true)]
public override string Text { get => base.Text; set { base.Text = value; Invalidate(); } }
[Browsable(true)]
public override Font Font { get => base.Font; set { base.Font = value; Invalidate(); } }
protected float _startAngle;
protected float _sweepAngle;
protected double _maxvalue;
protected int _gaugethickness;
protected int _needlelength;
protected float _needlesweep;
protected double _value;
protected Color gaugecolor;
protected Color needlecolor;
protected float _marklength;
protected Color _markcolor;
protected float _markthickness;
protected HorizontalAlignment _horizontalalignment;
protected VerticalAlignment _verticalalignment;
protected HorizontalAlignment _texthorizontalalignment;
protected VerticalAlignment _textverticalalignment;
protected float _offset_x;
protected float _offset_y;
#endregion
public DialGauge()
{
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
DoubleBuffered = true;
}
#region PAINT
protected override void OnPaint(PaintEventArgs e)
{
int size = ClientSize.Height - GaugeThickness;
float x = (GaugeThickness / 2) + OffsetX;
float y = (GaugeThickness / 2) + OffsetY;
if (this.HorizontalAlignment == HorizontalAlignment.Left)
{
x = ((size / 2) * -1) + OffsetX;
}
else if (this.HorizontalAlignment == HorizontalAlignment.Right)
{
x = (size / 2) + OffsetX;
}
if (this.VerticalAlignment == VerticalAlignment.Top)
{
y = ((size / 2) * -1) + OffsetY;
}
else if (this.VerticalAlignment == VerticalAlignment.Bottom)
{
y = (size / 2) + OffsetY;
}
PaintBackground(e, x, y);
PaintText(e, x, y, size, size);
PaintMarks(e, x, y);
PaintNeedle(e, x, y);
}
protected virtual void PaintBackground(PaintEventArgs e, float x, float y)
{
int size = ClientSize.Height - GaugeThickness;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
//Draw background
using (Pen p = new Pen(GaugeColor, GaugeThickness))
{
e.Graphics.DrawArc(p, x, y, size, size, StartAngle, SweepAngle);
}
}
protected virtual void PaintText(PaintEventArgs e, float x, float y, int width, int height)
{
TextFormatFlags horizontal = TextFormatFlags.HorizontalCenter;
TextFormatFlags vertical = TextFormatFlags.VerticalCenter;
if (this.TextAlignmentHorizontal == HorizontalAlignment.Left)
{
horizontal = TextFormatFlags.Left;
}
else if (this.TextAlignmentHorizontal == HorizontalAlignment.Right)
{
horizontal = TextFormatFlags.Right;
}
if (this.TextAlignmentVertical == VerticalAlignment.Top)
{
vertical = TextFormatFlags.Top;
}
else if (this.TextAlignmentVertical == VerticalAlignment.Bottom)
{
vertical = TextFormatFlags.Bottom;
}
Rectangle rect = new Rectangle((int)x, (int)y, width, height);
e.Graphics.FillEllipse(new SolidBrush(Color.Transparent), rect);
TextRenderer.DrawText(e.Graphics, this.Text, this.Font, rect,
this.ForeColor, horizontal | vertical);
}
protected virtual void PaintMarks(PaintEventArgs e, float x, float y)
{
int size = ClientSize.Height - GaugeThickness;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
//Draw Marks
float markLocation = 0.0f;
float spacing = SweepAngle / 10;
for (int i = 0; i < 11; i++)
{
using (Pen p = new Pen(MarkColor, MarkLength))
{
p.Alignment = PenAlignment.Inset;
e.Graphics.DrawArc(p, x, y, size, size, markLocation + StartAngle, MarkThickness);
markLocation += spacing;
}
}
}
protected virtual void PaintNeedle(PaintEventArgs e, float x, float y)
{
int size = ClientSize.Height - GaugeThickness;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
//Draw needle.
if (Value >= MaxValue) Value = MaxValue;
using (Pen p = new Pen(NeedleColor, NeedleLength))
{
p.Alignment = PenAlignment.Inset;
e.Graphics.DrawArc(p, x, y, size, size, StartAngle + GetNeedleAngle(), NeedleSweep);
}
base.OnPaint(e);
}
#endregion
protected float GetNeedleAngle()
{
float percentage = (float)(Value / MaxValue);
float angle = SweepAngle * percentage;
return angle;
}
}