我尝试使用标签,这是代码:
public partial class Form1 : Form
{
private readonly HttpClient _httpClient;
private readonly ProgressBar _progressBar;
private readonly Label _labelProgress;
private readonly Timer downloadTimer;
private readonly Radar radar;
public Form1()
{
InitializeComponent();
_httpClient = new HttpClient();
_progressBar = new ProgressBar
{
Size = lblNextTimeDownload.Size,
Minimum = 0,
Maximum = 100,
Value = 0,
};
_labelProgress = new Label
{
AutoSize = false,
TextAlign = ContentAlignment.MiddleCenter,
Font = new Font("Arial", 12, FontStyle.Regular),
};
_progressBar.Controls.Add(_labelProgress);
Controls.Add(_progressBar);
}
}
结果是
_labelProgress
位于进度条的左上角
如果在标签的实例中我添加以下行:
Dock = DockStyle.Fill,
像这样:
_labelProgress = new Label
{
AutoSize = false,
TextAlign = ContentAlignment.MiddleCenter,
Dock = DockStyle.Fill,
Font = new Font("Arial", 12, FontStyle.Regular),
};
然后Label的文本定位在ProgresBar的中心中间,但它也与整个ProgressBar重叠。
我的建议是避免为此使用标签。除此之外,当您的表单在 DpiAware 上下文中缩放时,您可能会发现它的缩放方式与 ProgressBar 不同。
您可以使用进度条的 DC 直接将百分比绘制到控件的表面上。为此重写 WndProc 并处理
WM_PAINT
。
当然,您需要构建一个自定义控件,覆盖它的 WndProc,捕获
WM_PAINT
,然后使用 GetWindowDc() 获取其设备上下文。Graphics.FromHdcInternal()
生成 Graphics 对象,然后将其传递给 TextRenderer.DrawText()
以将百分比呈现为文本。
ReleaseDC() 必须在之后调用,以释放 HDC。
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;
[ToolboxItem(true), DesignerCategory("code")]
public class ProgressBarEx : ProgressBar {
Color percentageColor = Color.Black;
int percentageDecimals = 0;
public ProgressBarEx() { }
[DefaultValue(typeof(Color), "Black")]
public Color PercentageColor {
get => percentageColor;
set {
if (percentageColor != value) {
percentageColor = value;
Invalidate();
}
}
}
[DefaultValue(0), Description("Number of decimals (0-4)")]
public int PercentageDecimals {
get => percentageDecimals;
set {
if (percentageDecimals != value) {
percentageDecimals = Math.Max(Math.Min(value, 4), 0);
Invalidate();
}
}
}
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
switch (m.Msg) {
case WM_PAINT:
if (!IsHandleCreated) return;
float percentage = (float)Value / Maximum;
percentage = float.IsNaN(percentage) ? 0 : percentage;
var hDC = GetWindowDC(this.Handle);
try {
using (var g = Graphics.FromHdcInternal(hDC)) {
TextRenderer.DrawText(g, percentage.ToString($"P{percentageDecimals}"),
Font, ClientRectangle, percentageColor);
}
}
finally {
if (hDC != IntPtr.Zero) ReleaseDC(this.Handle, hDC);
}
m.Result = IntPtr.Zero;
break;
default:
break;
}
}
const int WM_PAINT = 0x000F;
[DllImport("user32.dll")]
static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
}