Svi*_*ish 6 c# controls overriding onpaint winforms
我认为应该很容易创建一个ProgressBar
吸取一些文本的东西.但是,我不太清楚这里发生了什么......
我添加了以下两个覆盖:
protected override void OnPaintBackground(PaintEventArgs pevent)
{
base.OnPaintBackground(pevent);
var flags = TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter | TextFormatFlags.SingleLine | TextFormatFlags.WordEllipsis;
TextRenderer.DrawText(pevent.Graphics, "Hello", Font, Bounds, Color.Black, flags);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var flags = TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter | TextFormatFlags.SingleLine | TextFormatFlags.WordEllipsis;
TextRenderer.DrawText(e.Graphics, "Hello", Font, Bounds, Color.Black, flags);
}
Run Code Online (Sandbox Code Playgroud)
但是,我没有文本,甚至似乎都没有调用这些方法.这里发生了什么?
更新:由于到目前为止的两个答案,我已经得到它实际调用OnPaint
使用SetStyle(ControlStyles.UserPaint, true)
,我已经得到它通过发送new Rectangle(0, 0, Width, Height)
而不是在正确的地方绘制文本Bounds
.
我现在确实得到了文字,但是ProgressBar
它已经消失了...而且重点是将文本置于文本之上ProgressBar
.知道如何解决这个问题吗?
Chr*_*man 12
您可以覆盖WndProc并捕获WmPaint消息.
下面的示例在其中心绘制进度条的Text属性.
public class StatusProgressBar : ProgressBar
{
const int WmPaint = 15;
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
switch (m.Msg)
{
case WmPaint:
using (var graphics = Graphics.FromHwnd(Handle))
{
var textSize = graphics.MeasureString(Text, Font);
using(var textBrush = new SolidBrush(ForeColor))
graphics.DrawString(Text, Font, textBrush, (Width / 2) - (textSize.Width / 2), (Height / 2) - (textSize.Height / 2));
}
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我需要自己做这件事,我想我会发布一个简化的解决方案示例,因为我找不到任何例子.如果您使用ProgressBarRenderer类,实际上非常简单:
class MyProgressBar : ProgressBar
{
public MyProgressBar()
{
this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
Rectangle rect = this.ClientRectangle;
Graphics g = e.Graphics;
ProgressBarRenderer.DrawHorizontalBar( g, rect );
rect.Inflate(-3, -3);
if ( this.Value > 0 )
{
Rectangle clip = new Rectangle( rect.X, rect.Y, ( int )Math.Round( ( ( float )this.Value / this.Maximum ) * rect.Width ), rect.Height );
ProgressBarRenderer.DrawHorizontalChunks(g, clip);
}
// assumes this.Maximum == 100
string text = this.Value.ToString( ) + '%';
using ( Font f = new Font( FontFamily.GenericMonospace, 10 ) )
{
SizeF strLen = g.MeasureString( text, f );
Point location = new Point( ( int )( ( rect.Width / 2 ) - ( strLen.Width / 2 ) ), ( int )( ( rect.Height / 2 ) - ( strLen.Height / 2 ) ) );
g.DrawString( text, f, Brushes.Black, location );
}
}
}
Run Code Online (Sandbox Code Playgroud)
Bounds
您的问题是您作为 Rectangle 参数传入。Bounds 包含控件的高度和宽度,这是您想要的,但它还包含控件相对于父窗体的 Top 和 Left 属性,因此您的“Hello”在控件上偏移了多少控件在其父窗体上偏移。
替换Bounds
为new Rectangle(0, 0, this.Width, this.Height)
,您应该会看到“Hello”。