垂直颠倒的进度条?

发布于 2024-11-29 05:14:11 字数 521 浏览 0 评论 0原文

我想做一个垂直进度条,所以我发现了这个: 垂直进度条

但是现在如果你有水平进度条,你可以让它从左到右/从右到左工作,所以我希望我的垂直式从上到下工作,而不是像现在一样从下到上工作..

这可能吗?

这是我

public class VerticalProgressBar : ProgressBar
{
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.Style |= 0x04;
            return cp;
        }
    }
}

使用 C# .NET 3.5 Windows 窗体的代码

I wanted to do a Vertical Progress Bar so i found this:
Vertical progress bar

But now like if you have Horizitonal Progress Bar you can make it work from LeftToRight / RightToLeft so i want my Vertical one to Work from UpToDown and not from DownToUp like it works now..

Is it possible?

Here is my code

public class VerticalProgressBar : ProgressBar
{
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.Style |= 0x04;
            return cp;
        }
    }
}

I'm using C# .NET 3.5 Windows Forms

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

萧瑟寒风 2024-12-06 05:14:11

支持视觉样式的代码包含一些错误。此代码:

 ProgressBarRenderer.DrawVerticalBar(e.Graphics, e.ClipRectangle);

必须替换为此代码:

ProgressBarRenderer.DrawVerticalBar(e.Graphics, ClientRectangle);

并且我重新发布了没有此错误的完整源代码:

public class VerticalProgressBar : ProgressBar
    {
        protected override CreateParams CreateParams
        {
            get
            {
                // Avoid CA2122
                new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();

                CreateParams cp = base.CreateParams;
                cp.Style |= 0x04;
                return cp;
            }
        }

        public VerticalProgressBar()
        {
            // Enable OnPaint overriding
            this.SetStyle(ControlStyles.UserPaint, true);
        }

        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            if (ProgressBarRenderer.IsSupported)
            {
                ProgressBarRenderer.DrawVerticalBar(e.Graphics, ClientRectangle);

                const int HORIZ_OFFSET = 3;
                const int VERT_OFFSET = 2;

                if (this.Minimum == this.Maximum || (this.Value - Minimum) == 0 ||
                        this.Height < 2 * VERT_OFFSET || this.Width < 2 * VERT_OFFSET)
                    return;

                int barHeight = (this.Value - this.Minimum) * this.Height / (this.Maximum - this.Minimum);
                barHeight = Math.Min(barHeight, this.Height - 2 * VERT_OFFSET);
                int barWidth = this.Width - 2 * HORIZ_OFFSET;

                if (this.RightToLeftLayout && this.RightToLeft == System.Windows.Forms.RightToLeft.No)
                {
                    ProgressBarRenderer.DrawVerticalChunks(e.Graphics,
                            new Rectangle(HORIZ_OFFSET, VERT_OFFSET, barWidth, barHeight));
                }
                else
                {
                    int blockHeight = 10;
                    int wholeBarHeight = Convert.ToInt32(barHeight / blockHeight) * blockHeight;
                    int wholeBarY = this.Height - wholeBarHeight - VERT_OFFSET;
                    int restBarHeight = barHeight % blockHeight;
                    int restBarY = this.Height - barHeight - VERT_OFFSET;
                    ProgressBarRenderer.DrawVerticalChunks(e.Graphics,
                        new Rectangle(HORIZ_OFFSET, wholeBarY, barWidth, wholeBarHeight));
                    ProgressBarRenderer.DrawVerticalChunks(e.Graphics,
                        new Rectangle(HORIZ_OFFSET, restBarY, barWidth, restBarHeight));
                }
            }

            base.OnPaint(e);
        }
    }

Code, that support visual styles contains some bug. This code:

 ProgressBarRenderer.DrawVerticalBar(e.Graphics, e.ClipRectangle);

must be replaced with this one:

ProgressBarRenderer.DrawVerticalBar(e.Graphics, ClientRectangle);

And i repost full source code without this bug:

public class VerticalProgressBar : ProgressBar
    {
        protected override CreateParams CreateParams
        {
            get
            {
                // Avoid CA2122
                new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();

                CreateParams cp = base.CreateParams;
                cp.Style |= 0x04;
                return cp;
            }
        }

        public VerticalProgressBar()
        {
            // Enable OnPaint overriding
            this.SetStyle(ControlStyles.UserPaint, true);
        }

        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            if (ProgressBarRenderer.IsSupported)
            {
                ProgressBarRenderer.DrawVerticalBar(e.Graphics, ClientRectangle);

                const int HORIZ_OFFSET = 3;
                const int VERT_OFFSET = 2;

                if (this.Minimum == this.Maximum || (this.Value - Minimum) == 0 ||
                        this.Height < 2 * VERT_OFFSET || this.Width < 2 * VERT_OFFSET)
                    return;

                int barHeight = (this.Value - this.Minimum) * this.Height / (this.Maximum - this.Minimum);
                barHeight = Math.Min(barHeight, this.Height - 2 * VERT_OFFSET);
                int barWidth = this.Width - 2 * HORIZ_OFFSET;

                if (this.RightToLeftLayout && this.RightToLeft == System.Windows.Forms.RightToLeft.No)
                {
                    ProgressBarRenderer.DrawVerticalChunks(e.Graphics,
                            new Rectangle(HORIZ_OFFSET, VERT_OFFSET, barWidth, barHeight));
                }
                else
                {
                    int blockHeight = 10;
                    int wholeBarHeight = Convert.ToInt32(barHeight / blockHeight) * blockHeight;
                    int wholeBarY = this.Height - wholeBarHeight - VERT_OFFSET;
                    int restBarHeight = barHeight % blockHeight;
                    int restBarY = this.Height - barHeight - VERT_OFFSET;
                    ProgressBarRenderer.DrawVerticalChunks(e.Graphics,
                        new Rectangle(HORIZ_OFFSET, wholeBarY, barWidth, wholeBarHeight));
                    ProgressBarRenderer.DrawVerticalChunks(e.Graphics,
                        new Rectangle(HORIZ_OFFSET, restBarY, barWidth, restBarHeight));
                }
            }

            base.OnPaint(e);
        }
    }
辞取 2024-12-06 05:14:11

似乎没有任何 CreateParams 支持反向垂直 ProgressBar。这些是来自 Windows API 的样式参数:

#define PBS_SMOOTH          0x01
#define PBS_VERTICAL        0x04
#define PBS_MARQUEE         0x08
#define PBS_SMOOTHREVERSE   0x10

#define PBST_NORMAL         1
#define PBST_ERROR          2
#define PBST_PAUSED         3

我尝试更改 RightToLeft 值,但无济于事。似乎也没有办法任意旋转 Windows 窗体控件。

一种可能的解决方案是使用 WPF ProgressBar。您可以将其旋转 90 度,它应该可以满足您的要求。另一种选择是使用第三方进度条控件或创建自定义呈现的控件。渲染一个简单的平面进度条应该相当容易。

There doesn't seem to be any CreateParams that support inverted vertical ProgressBar. These are the style parameters from the Windows API:

#define PBS_SMOOTH          0x01
#define PBS_VERTICAL        0x04
#define PBS_MARQUEE         0x08
#define PBS_SMOOTHREVERSE   0x10

#define PBST_NORMAL         1
#define PBST_ERROR          2
#define PBST_PAUSED         3

I tried changing the RightToLeft values to no avail. There also doesn't seem to be a way to arbitrarily rotate a Windows Forms control.

A possible solution may be to use the WPF ProgressBar. You could rotate it 90 degrees and it should do what you're looking for. Another option is to use a third party Progressbar control or create a custom rendered one. It should be fairly easy to render a simple flat progressbar.

ζ澈沫 2024-12-06 05:14:11

你必须像这样重写 OnPaint() :

public class VerticalProgressBar : ProgressBar
{
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.Style |= 0x04;
            return cp;
        }
    }

    public VerticalProgressBar()
    {
        // Enable OnPaint overriding
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
    {
        Graphics dc = e.Graphics;

        if (this.Minimum == this.Maximum || (this.Value - Minimum) == 0)
            return;

        int width = this.Width;                                                                 // The bar width
        int height = (this.Value - this.Minimum) * this.Height / (this.Maximum - this.Minimum); // The bar height
        int x = 2;                          // The bottom-left x pos of the bar (or upper left on upsidedown bar)
        int y = this.Height - 1;            // The bottom-left y pos of the bar (or upper left on upsidedown bar)

        int blockheight = width * 3 / 4;    // The height of the block

        if (this.RightToLeftLayout && this.RightToLeft == System.Windows.Forms.RightToLeft.No)
            for (int currentpos = 0; currentpos < height; currentpos += blockheight + 1)
                dc.FillRectangle(new SolidBrush(this.ForeColor), x, currentpos, width, blockheight);
        else
            for (int currentpos = y; currentpos > y - height; currentpos -= blockheight + 1)
                dc.FillRectangle(new SolidBrush(this.ForeColor), x, currentpos - blockheight, width, blockheight);

        base.OnPaint(e);
    }
}

现在你可以像下面一样使用它
您链接的垂直进度栏和LeftToRight / RightToLeft功能将模仿普通ProgressBar中的进度条(关于进度绘制方向) )。

You have to override OnPaint() like this:

public class VerticalProgressBar : ProgressBar
{
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.Style |= 0x04;
            return cp;
        }
    }

    public VerticalProgressBar()
    {
        // Enable OnPaint overriding
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
    {
        Graphics dc = e.Graphics;

        if (this.Minimum == this.Maximum || (this.Value - Minimum) == 0)
            return;

        int width = this.Width;                                                                 // The bar width
        int height = (this.Value - this.Minimum) * this.Height / (this.Maximum - this.Minimum); // The bar height
        int x = 2;                          // The bottom-left x pos of the bar (or upper left on upsidedown bar)
        int y = this.Height - 1;            // The bottom-left y pos of the bar (or upper left on upsidedown bar)

        int blockheight = width * 3 / 4;    // The height of the block

        if (this.RightToLeftLayout && this.RightToLeft == System.Windows.Forms.RightToLeft.No)
            for (int currentpos = 0; currentpos < height; currentpos += blockheight + 1)
                dc.FillRectangle(new SolidBrush(this.ForeColor), x, currentpos, width, blockheight);
        else
            for (int currentpos = y; currentpos > y - height; currentpos -= blockheight + 1)
                dc.FillRectangle(new SolidBrush(this.ForeColor), x, currentpos - blockheight, width, blockheight);

        base.OnPaint(e);
    }
}

Now you can use it in the same way as
Vertical progress bar you linked and LeftToRight / RightToLeft functionality will mimic the one from normal ProgressBar (regarding progress drawing orientation).

余生一个溪 2024-12-06 05:14:11

我注意到上面的代码不适用于视觉样式。这是垂直进度条的改进版本,应涵盖视觉样式:

public class VerticalProgressBar : ProgressBar
{
    protected override CreateParams CreateParams
    {
        get
        {
            // Avoid CA2122
            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();  

            CreateParams cp = base.CreateParams;
            cp.Style |= 0x04;
            return cp;
        }
    }

    public VerticalProgressBar()
    {
        // Enable OnPaint overriding
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
    {
        if (ProgressBarRenderer.IsSupported)
        {
            ProgressBarRenderer.DrawVerticalBar(e.Graphics, e.ClipRectangle);

            const int HORIZ_OFFSET = 3;
            const int VERT_OFFSET = 2;

            if (this.Minimum == this.Maximum || (this.Value - Minimum) == 0 ||
                    this.Height < 2 * VERT_OFFSET || this.Width < 2 * VERT_OFFSET)
                return;

            int barHeight = (this.Value - this.Minimum) * this.Height / (this.Maximum - this.Minimum);
            barHeight = Math.Min(barHeight, this.Height - 2 * VERT_OFFSET);
            int barWidth = this.Width - 2 * HORIZ_OFFSET;

            if (this.RightToLeftLayout && this.RightToLeft == System.Windows.Forms.RightToLeft.No)
            {
                ProgressBarRenderer.DrawVerticalChunks(e.Graphics,
                        new Rectangle(HORIZ_OFFSET, VERT_OFFSET, barWidth, barHeight));
            }
            else
            {
                int blockHeight = 10;
                int wholeBarHeight = Convert.ToInt32(barHeight / blockHeight) * blockHeight;
                int wholeBarY = this.Height - wholeBarHeight - VERT_OFFSET;
                int restBarHeight = barHeight % blockHeight;
                int restBarY = this.Height - barHeight - VERT_OFFSET;
                ProgressBarRenderer.DrawVerticalChunks(e.Graphics,
                    new Rectangle(HORIZ_OFFSET, wholeBarY, barWidth, wholeBarHeight));
                ProgressBarRenderer.DrawVerticalChunks(e.Graphics,
                    new Rectangle(HORIZ_OFFSET, restBarY, barWidth, restBarHeight));
            }
        }

        base.OnPaint(e);
    }
}

我必须为自下而上的进度条绘制单独的块,因为我想保持其他进度条的外观和感觉。否则,该条形图就会看起来像是从中间绘制的。

I noticed the code above does not work well with visual styles. Here is an improved version of vertical progress bar that should cover visual styles:

public class VerticalProgressBar : ProgressBar
{
    protected override CreateParams CreateParams
    {
        get
        {
            // Avoid CA2122
            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();  

            CreateParams cp = base.CreateParams;
            cp.Style |= 0x04;
            return cp;
        }
    }

    public VerticalProgressBar()
    {
        // Enable OnPaint overriding
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
    {
        if (ProgressBarRenderer.IsSupported)
        {
            ProgressBarRenderer.DrawVerticalBar(e.Graphics, e.ClipRectangle);

            const int HORIZ_OFFSET = 3;
            const int VERT_OFFSET = 2;

            if (this.Minimum == this.Maximum || (this.Value - Minimum) == 0 ||
                    this.Height < 2 * VERT_OFFSET || this.Width < 2 * VERT_OFFSET)
                return;

            int barHeight = (this.Value - this.Minimum) * this.Height / (this.Maximum - this.Minimum);
            barHeight = Math.Min(barHeight, this.Height - 2 * VERT_OFFSET);
            int barWidth = this.Width - 2 * HORIZ_OFFSET;

            if (this.RightToLeftLayout && this.RightToLeft == System.Windows.Forms.RightToLeft.No)
            {
                ProgressBarRenderer.DrawVerticalChunks(e.Graphics,
                        new Rectangle(HORIZ_OFFSET, VERT_OFFSET, barWidth, barHeight));
            }
            else
            {
                int blockHeight = 10;
                int wholeBarHeight = Convert.ToInt32(barHeight / blockHeight) * blockHeight;
                int wholeBarY = this.Height - wholeBarHeight - VERT_OFFSET;
                int restBarHeight = barHeight % blockHeight;
                int restBarY = this.Height - barHeight - VERT_OFFSET;
                ProgressBarRenderer.DrawVerticalChunks(e.Graphics,
                    new Rectangle(HORIZ_OFFSET, wholeBarY, barWidth, wholeBarHeight));
                ProgressBarRenderer.DrawVerticalChunks(e.Graphics,
                    new Rectangle(HORIZ_OFFSET, restBarY, barWidth, restBarHeight));
            }
        }

        base.OnPaint(e);
    }
}

I had to draw separate chunks for bottom-up progress bar because I wanted to keep look and feel of other progress bars. Otherwise the bar would have appeared to be drawn from the middle.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文