我正在扩展内置进度条,能够以百分比显示进度,如下所示:
我试图在显示的文字中添加叠加层,因此它更具可读性。我已设法添加它,但现在我的文字未对齐:
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == 0x000F)
{
using (Graphics graphics = CreateGraphics())
using (var brush = new SolidBrush(ForeColor))
{
var newText = Math.Floor(((float) Value/Maximum)*100).ToString(CultureInfo.InvariantCulture) + '%';
SizeF textSize = graphics.MeasureString(newText, Font);
graphics.InterpolationMode = InterpolationMode.High;
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
graphics.CompositingQuality = CompositingQuality.HighQuality;
if (Overlay)
{
var p = new GraphicsPath();
p.AddString(
newText,
Font.FontFamily,
(int) Font.Style,
Font.SizeInPoints,
new Point((int) ((Width - textSize.Width)/2), (int) ((Height - textSize.Height)/2)),
StringFormat.GenericDefault);
graphics.FillPath(brush, p);
graphics.DrawPath(new Pen(Brushes.Black, 1), p);
}
else
{
graphics.DrawString(newText, Font, brush, (Width - textSize.Width) / 2, (Height - textSize.Height) / 2);
}
}
}
}
使用g.DrawPath
代替g.DrawString
时,如何修复文字大小和对齐方式
理想情况下,我想从第一个屏幕获取文本,但是有覆盖。
以下是我控制的完整代码:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Globalization;
using System.Windows.Forms;
namespace Misiu.Controls
{
public sealed class ProgressBarWithText : ProgressBar
{
public ProgressBarWithText()
{
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
ForeColor = Color.White;
BackColor = Color.Black;
}
protected override CreateParams CreateParams
{
get
{
CreateParams result = base.CreateParams;
if (Environment.OSVersion.Platform == PlatformID.Win32NT
&& Environment.OSVersion.Version.Major >= 6)
{
result.ExStyle |= 0x02000000; // WS_EX_COMPOSITED
}
return result;
}
}
public bool Overlay { get; set; }
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == 0x000F)
{
using (Graphics graphics = CreateGraphics())
using (var brush = new SolidBrush(ForeColor))
{
var newText = string.Empty;
switch (DisplayStyle)
{
case ProgressBarDisplayStyle.ValueAndMax:
newText = string.Format("{0}/{1}", Value, Maximum);
break;
case ProgressBarDisplayStyle.Text:
newText = Text;
break;
case ProgressBarDisplayStyle.Percentage:
newText = Math.Floor(((float) Value/Maximum)*100).ToString(CultureInfo.InvariantCulture) + '%';
break;
}
//var newText1 = DisplayStyle == ProgressBarDisplayStyle.Percentage ? Value == 0 ? "0%" : Math.Floor(((float)Value / Maximum) * 100).ToString(CultureInfo.InvariantCulture) + '%' : DisplayStyle == ProgressBarDisplayStyle.ValueAndMax ? string.Format("{0}/{1}", Value,Maximum) : Text;
SizeF textSize = graphics.MeasureString(newText, Font);
graphics.InterpolationMode = InterpolationMode.High;
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
graphics.CompositingQuality = CompositingQuality.HighQuality;
//graphics.SmoothingMode = SmoothingMode.AntiAlias;
if (Overlay)
{
var p = new GraphicsPath();
p.AddString(
newText,
Font.FontFamily,
(int) Font.Style,
Font.SizeInPoints,
new Point((int) ((Width - textSize.Width)/2), (int) ((Height - textSize.Height)/2)),
StringFormat.GenericDefault);
graphics.FillPath(brush, p);
graphics.DrawPath(new Pen(Brushes.Black, 1), p);
}
else
{
graphics.DrawString(newText, Font, brush, (Width - textSize.Width)/2, (Height - textSize.Height)/2);
}
}
}
}
private ProgressBarDisplayStyle _displayStyle = ProgressBarDisplayStyle.Percentage;
//Property to set to decide whether to print a % or Text
[EditorBrowsable(EditorBrowsableState.Always)]
[Browsable(true)]
public ProgressBarDisplayStyle DisplayStyle
{
get { return _displayStyle; }
set
{
if (_displayStyle == value) return;
_displayStyle = value;
Refresh();
}
}
[EditorBrowsable(EditorBrowsableState.Always)]
[Browsable(true)]
public override string Text
{
get { return base.Text; }
set
{
base.Text = value;
Refresh();
}
}
[EditorBrowsable(EditorBrowsableState.Always)]
[Browsable(true)]
public override Font Font
{
get { return base.Font; }
set
{
base.Font = value;
Refresh();
}
}
}
public enum ProgressBarDisplayStyle
{
Percentage,
ValueAndMax,
Text
}
}
修改
由于@Hans Passant,大部分问题都得到解决,但文字仍然未对齐,如下所示:
左进度条使用Lucida Handwriting, 30pt, style=Bold
和右'Microsoft Sans Serif,20pt。
文本稍微移动到右下角。
下面是我和我的对照的比较:
答案 0 :(得分:2)
我建议你通过StringFormat在控件的客户端矩形中对齐整个文本:
StringFormat format = new StringFormat()
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
float emSize = graphics.DpiY * Font.Size / 72;
var p = new GraphicsPath();
p.AddString(
newText,
Font.FontFamily,
(int)Font.Style,
emSize ,
ClientRectangle, // !!!
format); // !!!
这种方法可以摆脱任何测量和位置计算,它总是使事情正确地与我对齐。