C# C语言中的分段进度条#
我想使用分段进度条在我的应用程序中显示下载状态。例如: 有人知道如何在C#中实现它吗?提前感谢。CodeProject上的项目实现了一个分段的ProgressBar,可以实现这一点。以下是控件实现(在删除项目时复制到此处):C# C语言中的分段进度条#,c#,progress-bar,C#,Progress Bar,我想使用分段进度条在我的应用程序中显示下载状态。例如: 有人知道如何在C#中实现它吗?提前感谢。CodeProject上的项目实现了一个分段的ProgressBar,可以实现这一点。以下是控件实现(在删除项目时复制到此处): //下面的代码是由Guilherme Labigalini编写的 公共部分类BlockedProgressBar:控件 { 区块列表(BlockList);; /// ///MyProgressBar构造函数 /// 公共阻止的ProgressBar() { 初始化组
//下面的代码是由Guilherme Labigalini编写的
公共部分类BlockedProgressBar:控件
{
区块列表(BlockList);;
///
///MyProgressBar构造函数
///
公共阻止的ProgressBar()
{
初始化组件();
_blockList=新的blockList();
_方向=方向模式。水平;
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizerDraw | ControlStyles.DoubleBuffer,true);
}
///
///段的更新模式
///
[说明(“进度条更新模式”)]
[类别(“MyProgressBar”)]
[RefreshProperties(RefreshProperties.All)]
public BlockList.UpdateMode UpdateMode
{
获取{return\u blockList.Update;}
设置{u blockList.Update=value;}
}
///
///更改段的数量
///
[说明(“进度条段的长度”)]
[类别(“MyProgressBar”)]
[RefreshProperties(RefreshProperties.All)]
公共整数长度
{
获取{return\u blockList.Length;}
设置{u blockList.Length=value;this.Refresh();}
}
///
///获取或设置填充段
///
[可浏览(错误)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
公共int[]填充段
{
获取{return\u blockList.FilledSegments;}
设置{u blockList.FilledSegments=value;this.Refresh();}
}
///
///获取或设置段的完整列表
///
[可浏览(错误)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
公共布尔[]完整列表段
{
获取{return\u blockList.FullListSegment;}
设置{u blockList.FullListSegment=value;this.Refresh();}
}
///
///获取或设置线段的块列表
///
[可浏览(错误)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
公共列表阻止列表
{
获取{return\u blockList.List;}
设置{u blockList.List=value;this.Refresh();}
}
///
///杆的方向模式
///
公共枚举方向模式
{
水平=0,
垂直=1
}
专用方向模式_direction=DirectionMode.Horizontal;
///
///水平还是垂直
///
[说明(“进度条的填充方向”)]
[类别(“MyProgressBar”)]
[RefreshProperties(RefreshProperties.All)]
公共方向模式方向
{
获取{return\u direction;}
设置{u direction=value;this.Refresh();}
}
///
///OnPaint事件
///
///
受保护的覆盖无效OnPaint(PaintEventArgs pe)
{
Color color1=ControlPaint.Dark(此.PRECOLOR);
Color color2=ControlPaint.Light(此.PRECOLOR);
如果(_direction==DirectionMode.Horizontal)
{
int top=ClientRectangle.top+ClientRectangle.Height/2-1;
int height=ClientRectangle.height-top;
Draw矩形(pe、顶部、高度、颜色2、颜色1);
top=ClientRectangle.top;
高度=ClientRectangle.高度/2;
Draw矩形(pe、顶部、高度、颜色1、颜色2);
}
其他的
{
int left=ClientRectangle.left;
int width=ClientRectangle.width/2;
DrawRectangleV(pe、左侧、宽度、颜色1、颜色2);
左=ClientRectangle.left+ClientRectangle.Width/2;
宽度=ClientRectangle.宽度/2;
DrawRectangleV(pe、左侧、宽度、颜色2、颜色1);
}
pe.图形.绘图矩形(新钢笔(颜色.黑色),ClientRectangle);
基础漆(pe);
}
私有void DrawRectangleH(PaintEventArgs pe、int-top、int-height、Color-fromColor、Color-to-Color)
{
var rect=新矩形(ClientRectangle.Left,top,ClientRectangle.Width,height);
var brush=新的LinearGradientBrush(rect、fromColor、toColor、LinearGradientMode.Vertical);
如果(_blockList.Length>0)
{
矩形[]矩形=GetRectanglesH(顶部,高度);
如果(rects.Length>0)pe.Graphics.FillRectanges(画笔,矩形);//SystemBrush.Control
}
}
私有void DrawRectangleV(PaintEventArgs pe,int left,int width,Color fromColor,Color to Color)
{
var rect=新矩形(左,ClientRectangle.Top,宽,ClientRectangle.Height);
var brush=新的LinearGradientBrush(rect、fromColor、toColor、LinearGradientMode.Horizontal);
如果(_blockList.Length>0)
{
矩形[]矩形=GetRectanglesV(左,宽);
如果(rects.Length>0)pe.Graphics.FillRectanges(画笔,矩形);//SystemBrush.Control
}
}
私有矩形[]GetRectanglesH(整数顶部,整数高度)
{
var rects=新列表();
浮动xf=0;
int y=顶部;
int h=高度;
float pf=此.Width/(float)\u blockList.Length;
//h=这个高度;
foreach(blockList.List中的块)
{
如果(block.PercentProgress>0)
{
int x=转换为32(xf);
float wf=(pf*(block.BlockSize*block.PercentProgress/100))+xf-x;
int w=转换为32(wf);
添加(新的矩形(x,y,w,h));
}
xf+=pf*block.BlockSize;
}
返回rects.ToArray();
}
私有矩形[]GetRectanglesV(整数左,整数宽)
{
var rects=新列表();
浮点数yf=0;
int x=左;
int w=宽度
// The following code was written by Guilherme Labigalini
public partial class BlockedProgressBar : Control
{
BlockList _blockList;
/// <summary>
/// MyProgressBar Constructor
/// </summary>
public BlockedProgressBar()
{
InitializeComponent();
_blockList = new BlockList();
_direction = DirectionMode.Horizontal;
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer, true);
}
/// <summary>
/// Update mode of segments
/// </summary>
[Description("The mode of update of progress bar")]
[Category("MyProgressBar")]
[RefreshProperties(RefreshProperties.All)]
public BlockList.UpdateMode UpdateMode
{
get { return _blockList.Update; }
set { _blockList.Update = value; }
}
/// <summary>
/// Change quantity of segments
/// </summary>
[Description("The length of segments of progress bar")]
[Category("MyProgressBar")]
[RefreshProperties(RefreshProperties.All)]
public int Length
{
get { return _blockList.Length; }
set { _blockList.Length = value; this.Refresh(); }
}
/// <summary>
/// Get or set filled segments
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int[] FilledSegments
{
get { return _blockList.FilledSegments; }
set { _blockList.FilledSegments = value; this.Refresh(); }
}
/// <summary>
/// Get or sets the full list of segments
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool[] FullListSegment
{
get { return _blockList.FullListSegment; }
set { _blockList.FullListSegment = value; this.Refresh(); }
}
/// <summary>
/// Get or set the block list of segments
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public List<Block> BlockList
{
get { return _blockList.List; }
set { _blockList.List = value; this.Refresh(); }
}
/// <summary>
/// DirectionMode of bar
/// </summary>
public enum DirectionMode
{
Horizontal = 0,
Vertical = 1
}
private DirectionMode _direction = DirectionMode.Horizontal;
/// <summary>
/// Horizontal or Vertical
/// </summary>
[Description("The filling direction of progress bar")]
[Category("MyProgressBar")]
[RefreshProperties(RefreshProperties.All)]
public DirectionMode Direction
{
get { return _direction; }
set { _direction = value; this.Refresh(); }
}
/// <summary>
/// OnPaint event
/// </summary>
/// <param name="pe"></param>
protected override void OnPaint(PaintEventArgs pe)
{
Color color1 = ControlPaint.Dark(this.ForeColor);
Color color2 = ControlPaint.Light(this.ForeColor);
if (_direction == DirectionMode.Horizontal)
{
int top = ClientRectangle.Top + ClientRectangle.Height / 2 - 1;
int height = ClientRectangle.Height - top;
DrawRectangleH(pe, top, height, color2, color1);
top = ClientRectangle.Top;
height = ClientRectangle.Height / 2;
DrawRectangleH(pe, top, height, color1, color2);
}
else
{
int left = ClientRectangle.Left;
int width = ClientRectangle.Width / 2;
DrawRectangleV(pe, left, width, color1, color2);
left = ClientRectangle.Left + ClientRectangle.Width / 2;
width = ClientRectangle.Width / 2;
DrawRectangleV(pe, left, width, color2, color1);
}
pe.Graphics.DrawRectangle(new Pen(Color.Black), ClientRectangle);
base.OnPaint(pe);
}
private void DrawRectangleH(PaintEventArgs pe, int top, int height, Color fromColor, Color toColor)
{
var rect = new Rectangle(ClientRectangle.Left, top, ClientRectangle.Width, height);
var brush = new LinearGradientBrush(rect, fromColor, toColor, LinearGradientMode.Vertical);
if (_blockList.Length > 0)
{
Rectangle[] rects = GetRectanglesH(top, height);
if (rects.Length > 0) pe.Graphics.FillRectangles(brush, rects); //SystemBrushes.Control
}
}
private void DrawRectangleV(PaintEventArgs pe, int left, int width, Color fromColor, Color toColor)
{
var rect = new Rectangle(left, ClientRectangle.Top, width, ClientRectangle.Height);
var brush = new LinearGradientBrush(rect, fromColor, toColor, LinearGradientMode.Horizontal);
if (_blockList.Length > 0)
{
Rectangle[] rects = GetRectanglesV(left, width);
if (rects.Length > 0) pe.Graphics.FillRectangles(brush, rects); //SystemBrushes.Control
}
}
private Rectangle[] GetRectanglesH(int top, int height)
{
var rects = new List<Rectangle>();
float xf = 0;
int y = top;
int h = height;
float pf = this.Width / (float)_blockList.Length;
//h = this.Height;
foreach (Block block in _blockList.List)
{
if (block.PercentProgress > 0)
{
int x = Convert.ToInt32(xf);
float wf = (pf * (block.BlockSize * block.PercentProgress / 100)) + xf - x;
int w = Convert.ToInt32(wf);
rects.Add(new Rectangle(x, y, w, h));
}
xf += pf * block.BlockSize;
}
return rects.ToArray();
}
private Rectangle[] GetRectanglesV(int left, int width)
{
var rects = new List<Rectangle>();
float yf = 0;
int x = left;
int w = width;
float pf = this.Height / (float)_blockList.Length;
//w = this.Width;
foreach (Block block in _blockList.List)
{
if (block.PercentProgress > 0)
{
int y = Convert.ToInt32(yf);
float hf = (pf * (block.BlockSize * block.PercentProgress / 100)) + yf - y;
int h = Convert.ToInt32(hf);
rects.Add(new Rectangle(x, y, w, h));
}
yf += pf * block.BlockSize;
}
return rects.ToArray();
}
}
[Serializable]
public class BlockList
{
private int _length;
private List<Block> _blockList;
public BlockList()
{
_blockList = new List<Block>();
}
public enum UpdateMode
{
All,
FilledSegments,
FullListSegment,
BlockList
}
/// <summary>
/// Update mode of segments
/// </summary>
public UpdateMode Update = UpdateMode.All;
/// <summary>
/// Change quantity of segments
/// </summary>
public int Length
{
get { return _length; }
set
{
if (_length != value && value > 0)
{
var bools = FullListSegment;
var bools2 = new bool[value];
for (int i = 0; i < bools.Length; i++)
{
bools2[i] = bools[i];
}
FullListSegment = bools2;
}
}
}
/// <summary>
/// Get or set filled segments
/// </summary>
public int[] FilledSegments
{
get
{
var bools = FullListSegment;
var filled = new List<int>();
for (int i = 0; i < bools.Length; i++)
{
if (bools[i])
{
filled.Add(i);
}
}
return filled.ToArray();
}
set
{
if (Update != UpdateMode.All && Update != UpdateMode.FilledSegments)
throw new InvalidOperationException();
if (value != null)
if (value.Length > 0)
{
var bools = FullListSegment;
for (int i = 0; i < value.Length; i++)
{
bools.SetValue(true, value[i]);
}
FullListSegment = bools;
}
}
}
/// <summary>
/// Get or sets the full list of segments
/// </summary>
public bool[] FullListSegment
{
get
{
int sizeAnterior = 0;
var bools = new bool[_length];
if (bools.Length > 0)
{
foreach (Block block in _blockList)
{
for (int i = 0; i < Convert.ToInt32(block.BlockSize * block.PercentProgress / 100); i++)
bools.SetValue(true, i + sizeAnterior);
sizeAnterior += Convert.ToInt32(block.BlockSize);
}
}
return bools;
}
set
{
if (Update != UpdateMode.All && Update != UpdateMode.FullListSegment)
throw new InvalidOperationException();
bool bOld = false;
int qtd = 0;
int filled = 0;
if (value != null)
{
if (value.Length > 0)
{
_blockList.Clear();
float percent;
foreach (bool b in value)
{
if (b == bOld)
qtd++;
else
{
if (bOld)
filled = qtd;
else if (filled + qtd > 0)
{
percent = filled / (float)(filled + qtd) * 100;
_blockList.Add(new Block(filled + qtd, percent));
}
qtd = 1;
bOld = b;
}
}
if (filled + qtd > 0)
{
percent = filled / (float)(filled + qtd) * 100;
_blockList.Add(new Block(filled + qtd, percent));
}
_length = value.Length;
}
}
else
{
_length = 0;
}
}
}
/// <summary>
/// Get or set the block list of segments
/// </summary>
public List<Block> List
{
get
{
return _blockList;
}
set
{
if (Update != UpdateMode.All && Update != UpdateMode.BlockList)
throw new InvalidOperationException();
float size = 0;
_blockList = value;
if (_blockList != null)
size += _blockList.Sum(block => block.BlockSize);
_length = Convert.ToInt32(size);
}
}
}
[Serializable]
public class Block
{
private float _blockSize;
private float _percentProgress;
public Block(float blockSize, float percentProgress)
{
this.BlockSize = blockSize;
this.PercentProgress = percentProgress;
}
public float BlockSize
{
get { return _blockSize; }
set { _blockSize = value; }
}
public float PercentProgress
{
get { return _percentProgress; }
set { _percentProgress = value; }
}
}
blockedProgressBar1.BlockList = new List<Block>(5)
{
new Block(100,20),
new Block(100,50),
new Block(100,70),
new Block(100,99),
new Block(100,60),
new Block(100,35),
};