【发布时间】:2015-12-03 16:24:16
【问题描述】:
我正在扩展内置进度条,能够以百分比显示进度,如下所示:
我正在尝试将叠加层添加到显示的文本中,这样它会更具可读性。我已设法添加它,但现在我的文本未对齐:
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。
文字向右下角移动了一点。
下面是我的控件有和没有覆盖的比较:
【问题讨论】:
-
当您提供位置时,而不是使用表单的高度和宽度,将面板添加到表单并将 DockStyle 更改为“填充”,然后使用此面板的高度和宽度。
-
@Rariolu 我正在扩展 ProgressBar 控件,所以没有表单。我将在我的问题中添加完整代码