Visual Studio 半圆进度条
Visual Studio Half Circle Progress Bars
我想实现半圆形进度条,但我没有足够的经验visual studio,我确实找到了一个圆形进度条 Nuget 包,它可以做完整的圆形,但我做不到'找不到成功制作一半的方法(甚至尝试修改 CircularProgressBar Nuget 包的源代码),是否有人可以提供提示或实现方法。谢谢
What circular progress bar Nuget pack offers
Half-circular progress bar that I am trying to implement on my design
这可能不是最好的解决方案,但您可以在圆形进度条项目的下半部分添加一个面板。然后将 StartAngle
设置为 180,将 Maximum
设置为最大可达值的两倍。这里有一小段示例(快速而肮脏):
您可以子class 并创建自定义半圆进度 控件。你要做的只是180°的计算和绘图,而不是360°。
从 Label
控件导出新的 class 并导入:
using System;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.ComponentModel;
并封装:
- 进度控件的关键属性,
Value
、Minimum
和 Maximum
。
- 用于绘制进度、轨道大小、轨道和值颜色的属性。
- 用于通知订阅者值更改的自定义事件。
- 调用
Graphics.DrawArc
方法绘制轨道和值弧的绘图例程。
[DesignerCategory("Code")]
[DefaultProperty("Value")]
[DefaultEvent("ValueChanged")]
[ToolboxItem(typeof(ToolboxItem))]
[ToolboxBitmap(typeof(ProgressBar))]
public class SemiCircleProgress : Label
{
#region ctor
public SemiCircleProgress() : base() { }
#endregion
#region Properties
private int _value;
[DefaultValue(0)]
public int Value
{
get => _value;
set
{
if (_value != value)
{
_value = value < Minimum ? Minimum : value > Maximum ? Maximum : value;
Invalidate();
OnValueChanged(new EventArgs());
}
}
}
private int _min;
[DefaultValue(0)]
public int Minimum
{
get => _min;
set
{
if (_min != value)
{
_min = Math.Max(value, 0);
if (value > _value) _value = value;
if (value > _max) _max = value;
Invalidate();
}
}
}
private int _max = 100;
[DefaultValue(100)]
public int Maximum
{
get => _max;
set
{
if (_max != value)
{
if (value < 1) value = 1;
if (value < _value) _value = value;
_max = value;
Invalidate();
}
}
}
private int _trackSize = 10;
[DefaultValue(10)]
public int TrackSize
{
get => _trackSize;
set
{
if (_trackSize != value)
{
_trackSize = value;
Invalidate();
}
}
}
private Color _trackColor = Color.Gray;
[DefaultValue(typeof(Color), "Gray")]
public Color TrackColor
{
get => _trackColor;
set
{
if (_trackColor != value)
{
_trackColor = value;
Invalidate();
}
}
}
private Color _valueColor = Color.FromArgb(255, 128, 0);
[DefaultValue(typeof(Color), "255, 128, 0")]
public Color ValueColor
{
get => _valueColor;
set
{
if (_valueColor != value)
{
_valueColor = value;
Invalidate();
}
}
}
private bool _showValue;
[DefaultValue(false)]
public bool ShowValue
{
get => _showValue;
set
{
if (_showValue != value)
{
_showValue = value;
Invalidate();
}
}
}
protected override Size DefaultSize => new Size(100, 100);
#endregion
#region Paint
protected override void OnPaint(PaintEventArgs e)
{
var g = e.Graphics;
var r = new Rectangle(_trackSize, _trackSize,
Math.Max(_trackSize * 2, Width - _trackSize * 2),
Math.Max(_trackSize * 2, (Height - _trackSize * 2) * 2));
using (var pnTrack = new Pen(_trackColor, _trackSize))
{
g.Clear(BackColor);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.PixelOffsetMode = PixelOffsetMode.Half;
g.DrawArc(pnTrack, r, 180, 180);
if (Value > Minimum)
{
var val = (int)Math.Round(180d / Maximum * Value);
pnTrack.Color = _valueColor;
// pnTrack.Width -= 2; // uncomment and try...
g.DrawArc(pnTrack, r, 180, val);
}
}
if (_showValue)
{
TextRenderer.DrawText(g, Value.ToString(), Font, r, ForeColor,
TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
}
}
#endregion
#region Events
public event EventHandler ValueChanged;
protected virtual void OnValueChanged(EventArgs e) =>
ValueChanged?.Invoke(this, e);
#endregion
}
ToDo : 隐藏基地不使用的属性 class:
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override string Text { get => base.Text; set => base.Text = value; }
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new Image Image { get; set; }
// ...etc.
我想实现半圆形进度条,但我没有足够的经验visual studio,我确实找到了一个圆形进度条 Nuget 包,它可以做完整的圆形,但我做不到'找不到成功制作一半的方法(甚至尝试修改 CircularProgressBar Nuget 包的源代码),是否有人可以提供提示或实现方法。谢谢
What circular progress bar Nuget pack offers
Half-circular progress bar that I am trying to implement on my design
这可能不是最好的解决方案,但您可以在圆形进度条项目的下半部分添加一个面板。然后将 StartAngle
设置为 180,将 Maximum
设置为最大可达值的两倍。这里有一小段示例(快速而肮脏):
您可以子class 并创建自定义半圆进度 控件。你要做的只是180°的计算和绘图,而不是360°。
从 Label
控件导出新的 class 并导入:
using System;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.ComponentModel;
并封装:
- 进度控件的关键属性,
Value
、Minimum
和Maximum
。 - 用于绘制进度、轨道大小、轨道和值颜色的属性。
- 用于通知订阅者值更改的自定义事件。
- 调用
Graphics.DrawArc
方法绘制轨道和值弧的绘图例程。
[DesignerCategory("Code")]
[DefaultProperty("Value")]
[DefaultEvent("ValueChanged")]
[ToolboxItem(typeof(ToolboxItem))]
[ToolboxBitmap(typeof(ProgressBar))]
public class SemiCircleProgress : Label
{
#region ctor
public SemiCircleProgress() : base() { }
#endregion
#region Properties
private int _value;
[DefaultValue(0)]
public int Value
{
get => _value;
set
{
if (_value != value)
{
_value = value < Minimum ? Minimum : value > Maximum ? Maximum : value;
Invalidate();
OnValueChanged(new EventArgs());
}
}
}
private int _min;
[DefaultValue(0)]
public int Minimum
{
get => _min;
set
{
if (_min != value)
{
_min = Math.Max(value, 0);
if (value > _value) _value = value;
if (value > _max) _max = value;
Invalidate();
}
}
}
private int _max = 100;
[DefaultValue(100)]
public int Maximum
{
get => _max;
set
{
if (_max != value)
{
if (value < 1) value = 1;
if (value < _value) _value = value;
_max = value;
Invalidate();
}
}
}
private int _trackSize = 10;
[DefaultValue(10)]
public int TrackSize
{
get => _trackSize;
set
{
if (_trackSize != value)
{
_trackSize = value;
Invalidate();
}
}
}
private Color _trackColor = Color.Gray;
[DefaultValue(typeof(Color), "Gray")]
public Color TrackColor
{
get => _trackColor;
set
{
if (_trackColor != value)
{
_trackColor = value;
Invalidate();
}
}
}
private Color _valueColor = Color.FromArgb(255, 128, 0);
[DefaultValue(typeof(Color), "255, 128, 0")]
public Color ValueColor
{
get => _valueColor;
set
{
if (_valueColor != value)
{
_valueColor = value;
Invalidate();
}
}
}
private bool _showValue;
[DefaultValue(false)]
public bool ShowValue
{
get => _showValue;
set
{
if (_showValue != value)
{
_showValue = value;
Invalidate();
}
}
}
protected override Size DefaultSize => new Size(100, 100);
#endregion
#region Paint
protected override void OnPaint(PaintEventArgs e)
{
var g = e.Graphics;
var r = new Rectangle(_trackSize, _trackSize,
Math.Max(_trackSize * 2, Width - _trackSize * 2),
Math.Max(_trackSize * 2, (Height - _trackSize * 2) * 2));
using (var pnTrack = new Pen(_trackColor, _trackSize))
{
g.Clear(BackColor);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.PixelOffsetMode = PixelOffsetMode.Half;
g.DrawArc(pnTrack, r, 180, 180);
if (Value > Minimum)
{
var val = (int)Math.Round(180d / Maximum * Value);
pnTrack.Color = _valueColor;
// pnTrack.Width -= 2; // uncomment and try...
g.DrawArc(pnTrack, r, 180, val);
}
}
if (_showValue)
{
TextRenderer.DrawText(g, Value.ToString(), Font, r, ForeColor,
TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
}
}
#endregion
#region Events
public event EventHandler ValueChanged;
protected virtual void OnValueChanged(EventArgs e) =>
ValueChanged?.Invoke(this, e);
#endregion
}
ToDo : 隐藏基地不使用的属性 class:
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override string Text { get => base.Text; set => base.Text = value; }
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new Image Image { get; set; }
// ...etc.