C# C语言中的分段进度条#

C# C语言中的分段进度条#,c#,progress-bar,C#,Progress Bar,我想使用分段进度条在我的应用程序中显示下载状态。例如: 有人知道如何在C#中实现它吗?提前感谢。CodeProject上的项目实现了一个分段的ProgressBar,可以实现这一点。以下是控件实现(在删除项目时复制到此处): //下面的代码是由Guilherme Labigalini编写的 公共部分类BlockedProgressBar:控件 { 区块列表(BlockList);; /// ///MyProgressBar构造函数 /// 公共阻止的ProgressBar() { 初始化组

我想使用分段进度条在我的应用程序中显示下载状态。例如:

有人知道如何在C#中实现它吗?提前感谢。

CodeProject上的项目实现了一个分段的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),
            };