Как изменить цвет progressbar в С#.NET 3.5?

Я хотел бы сделать две вещи на панели выполнения.

  • Измените зеленый цвет на красный.
  • Удалите блоки и сделайте их одним цветом.

Любая информация об этих двух вещах, о которых мне интересно, как это сделать, будет великолепно оценена!

Спасибо.

Ответ 1

Поскольку предыдущие ответы не работают с визуальными стилями. Вам, вероятно, потребуется создать свой собственный класс или расширить индикатор выполнения:

public class NewProgressBar : ProgressBar
{
    public NewProgressBar()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Rectangle rec = e.ClipRectangle;

        rec.Width = (int)(rec.Width * ((double)Value / Maximum)) - 4;
        if(ProgressBarRenderer.IsSupported)
           ProgressBarRenderer.DrawHorizontalBar(e.Graphics, e.ClipRectangle);
        rec.Height = rec.Height - 4;
        e.Graphics.FillRectangle(Brushes.Red, 2, 2, rec.Width, rec.Height);
    }
}

EDIT: обновленный код, чтобы индикатор выполнения использовал визуальный стиль для фона

Ответ 2

Хорошо, мне потребовалось некоторое время, чтобы прочитать все ответы и ссылки. Вот что я получил от них:

Примеры результатов

Принятый ответ отключает визуальные стили, он позволяет вам устанавливать цвет на все, что угодно, но результат выглядит просто:

enter image description here

Используя следующий метод, вы можете получить что-то вроде этого:

enter image description here

Как

Во-первых, включите это, если у вас нет: using System.Runtime.InteropServices;

Во-вторых, вы можете создать этот новый класс или поместить его код в существующий static не общий класс:

public static class ModifyProgressBarColor
{
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr w, IntPtr l);
    public static void SetState(this ProgressBar pBar, int state)
    {
        SendMessage(pBar.Handle, 1040, (IntPtr)state, IntPtr.Zero);
    }
}

Теперь, чтобы использовать его, просто позвоните:

ModifyProgressBarColor.SetState(progressBar1, 2);

Обратите внимание на второй параметр в SetState, 1 = normal (зеленый); 2 = ошибка (красный); 3 = предупреждение (желтый).

Надеюсь, поможет!

Ответ 3

Это бесплатная версия наиболее приемлемого кода, которую вы можете найти в качестве ответов на этот вопрос. Все они относятся к плакатам этих фатальных ответов. Спасибо Дасти, Крису, Мэтту и Джошу!

Подобно запросу "Fueled" в одном из комментариев, мне также нужна версия, которая вела себя немного больше... профессионализма. Этот код поддерживает стили, как в предыдущем коде, но добавляет визуализацию изображения вне экрана и графическую буферизацию (и правильно размещает графический объект).

Результат: все хорошее, и не мерцает.:)

public class NewProgressBar : ProgressBar
{
    public NewProgressBar()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaintBackground(PaintEventArgs pevent)
    {
        // None... Helps control the flicker.
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        const int inset = 2; // A single inset value to control teh sizing of the inner rect.

        using (Image offscreenImage = new Bitmap(this.Width, this.Height))
        {
            using (Graphics offscreen = Graphics.FromImage(offscreenImage))
            {
                Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);

                if (ProgressBarRenderer.IsSupported)
                    ProgressBarRenderer.DrawHorizontalBar(offscreen, rect);

                rect.Inflate(new Size(-inset, -inset)); // Deflate inner rect.
                rect.Width = (int)(rect.Width * ((double)this.Value / this.Maximum));
                if (rect.Width == 0) rect.Width = 1; // Can't draw rec with width of 0.

                LinearGradientBrush brush = new LinearGradientBrush(rect, this.BackColor, this.ForeColor, LinearGradientMode.Vertical);
                offscreen.FillRectangle(brush, inset, inset, rect.Width, rect.Height);

                e.Graphics.DrawImage(offscreenImage, 0, 0);
                offscreenImage.Dispose();
            }
        }
    }
}

Ответ 4

В дизайнере вам просто нужно установить свойство ForeColor на любой цвет. В случае красного цвета для него есть предопределенный цвет.

Чтобы сделать это в коде (С#), выполните следующие действия:

pgs.ForeColor = Color.Red;

Изменить: О да, также настройте стиль на непрерывный. В коде, например:

pgs.Style = System.Windows.Forms.ProgressBarStyle.Continuous;

Другое Редактировать: Вам также потребуется удалить строку, которая читает Application.EnableVisualStyles() из вашего Program.cs (или аналогичного). Если вы не можете сделать это, потому что хотите, чтобы в остальной части приложения были визуальные стили, я бы предложил рисовать элемент управления самостоятельно или перейти к WPF, так как это простое с WPF. Вы можете найти учебник о том, как владелец рисует индикатор выполнения в codeplex

Ответ 5

Используя ответы Мэтта Блейна и Криса Персикетти, я создал индикатор выполнения, который выглядит немного лучше, позволяя бесконечный выбор цвета (в основном я изменил одну строку в решении Matt):

ProgressBarEx:

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace QuantumConcepts.Common.Forms.UI.Controls
{
    public class ProgressBarEx : ProgressBar
    {
        public ProgressBarEx()
        {
            this.SetStyle(ControlStyles.UserPaint, true);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            LinearGradientBrush brush = null;
            Rectangle rec = new Rectangle(0, 0, this.Width, this.Height);
            double scaleFactor = (((double)Value - (double)Minimum) / ((double)Maximum - (double)Minimum));

            if (ProgressBarRenderer.IsSupported)
                ProgressBarRenderer.DrawHorizontalBar(e.Graphics, rec);

            rec.Width = (int)((rec.Width * scaleFactor) - 4);
            rec.Height -= 4;
            brush = new LinearGradientBrush(rec, this.ForeColor, this.BackColor, LinearGradientMode.Vertical);
            e.Graphics.FillRectangle(brush, 2, 2, rec.Width, rec.Height);
        }
    }
}

Применение:

progressBar.ForeColor = Color.FromArgb(255, 0, 0);
progressBar.BackColor = Color.FromArgb(150, 0, 0);

Результаты

You can use any gradient you like!

Скачать

https://skydrive.live.com/?cid=0EDE5D21BDC5F270&id=EDE5D21BDC5F270%21160&sc=documents#

Ответ 6

Модификатор к ответу пылеуловителя. (Мне не хватает репутации для его редактирования.) Как и его ответ, он работает с включенными "Визуальными стилями". Вы можете просто установить свойство свойства ForeColor в любом виде.

using System;
using System.Windows.Forms;
using System.Drawing;

public class ProgressBarEx : ProgressBar
{
    private SolidBrush brush = null;

    public ProgressBarEx()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        if (brush == null || brush.Color != this.ForeColor)
            brush = new SolidBrush(this.ForeColor);

        Rectangle rec = new Rectangle(0, 0, this.Width, this.Height);
        if (ProgressBarRenderer.IsSupported)
            ProgressBarRenderer.DrawHorizontalBar(e.Graphics, rec);
        rec.Width = (int)(rec.Width * ((double)Value / Maximum)) - 4;
        rec.Height = rec.Height - 4;
        e.Graphics.FillRectangle(brush, 2, 2, rec.Width, rec.Height);
    }
}

Ответ 7

Я просто помещаю это в статический класс.

  const int WM_USER = 0x400;
  const int PBM_SETSTATE = WM_USER + 16;
  const int PBM_GETSTATE = WM_USER + 17;

  [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
  static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

  public enum ProgressBarStateEnum : int
  {
   Normal = 1,
   Error = 2,
   Paused = 3,
  }

  public static ProgressBarStateEnum GetState(this ProgressBar pBar)
  {
   return (ProgressBarStateEnum)(int)SendMessage(pBar.Handle, PBM_GETSTATE, IntPtr.Zero, IntPtr.Zero);
  }

  public static void SetState(this ProgressBar pBar, ProgressBarStateEnum state)
  {
   SendMessage(pBar.Handle, PBM_SETSTATE, (IntPtr)state, IntPtr.Zero);
  } 

Надеюсь, что это поможет,

Марк

Ответ 8

Обычно индикатор выполнения либо имеет тематическое значение, либо отличает предпочтения пользователя. Поэтому для изменения цвета вам нужно отключить визуальные стили и установить ForeColor или самостоятельно нарисовать элемент управления.

Что касается непрерывного стиля вместо блоков, вы можете установить свойство Style:

pBar.Style = ProgressBarStyle.Continuous;

Ответ 9

ИЗМЕНИТЬ

По звукам вещей вы используете тему XP, у которой есть прог-бар с зеленым блоком. Попробуйте перевернуть свой стиль пользовательского интерфейса в Windows Classic и повторите тест, но вам может потребоваться реализовать свое собственное событие OnPaint, чтобы заставить его делать то, что вы хотите, во всех стилях пользовательского интерфейса.

Или, как заметил кто-то другой, отключите VisualStyles для вашего приложения.

Оригинал

Насколько я знаю, рендеринг полосы прогресса происходит в соответствии с выбранным вами стилем темы Windows (win2K, xp, vista)

Вы можете изменить цвет, установив свойство

ProgressBar.ForeColor

Я не уверен, что вы можете сделать гораздо больше...

выполняет некоторые поисковые запросы

Вот статья из MS KB о создании "гладкой" строки выполнения

http://support.microsoft.com/kb/323116

Ответ 11

Я предлагаю вам также взглянуть на эту статью на CodeProject: Progress-O-Doom. Это здорово!

Ответ 12

Все эти методы не работают для меня, но этот метод позволяет изменить его на строку цвета.

Обратите внимание, что я нашел этот код из другого места в StackOverflow и немного изменил его. Я с тех пор забыл, где я нашел этот код, и я не могу связать его из-за этого, так извините за это.

Но в любом случае я надеюсь, что этот код поможет кому-то, кто действительно помог мне.

private void ProgressBar_MouseDown(object sender, MouseButtonEventArgs e)
    {
        var converter = new System.Windows.Media.BrushConverter();
        var brush = (Brush)converter.ConvertFromString("#FFB6D301");
        ProgressBar.Foreground = brush;
    }

Если имя "ProgressBar" используется, замените его собственным именем панели выполнения. Вы также можете инициировать это событие с помощью других аргументов, просто убедитесь, что его внутри скобок где-то.

Ответ 13

Измените Color и Value (мгновенное изменение)

Поместите using System.Runtime.InteropServices; вверху...

Вызов с помощью ColorBar.SetState(progressBar1, ColorBar.Color.Yellow, myValue);

Я заметил, что если вы измените значение бара (насколько оно велико), то он не изменится, если он отличается от цвета по умолчанию. Я взял user1032613 код и добавил параметр Value.

public static class ColorBar
{
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr w, IntPtr l);
    public enum Color { None, Green, Red, Yellow }

    public static void SetState(this ProgressBar pBar, Color newColor, int newValue)
    {
        if (pBar.Value == pBar.Minimum)  // If it has not been painted yet, paint the whole thing using defualt color...
        {                                // Max move is instant and this keeps the initial move from going out slowly 
            pBar.Value = pBar.Maximum;   // in wrong color on first painting
            SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);
        }
        pBar.Value = newValue;
        SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);     // run it out to the correct spot in default
        SendMessage(pBar.Handle, 1040, (IntPtr)(int)newColor, IntPtr.Zero);        // now turn it the correct color
    }

}

Ответ 14

На всякий случай, если кто-то ищет другой вариант... вы можете расширить панель, использовать ее как фон (белый или любой другой), добавить другую панель внутри нее для переднего плана (движущаяся панель). Затем у вас есть полный контроль, изменяющий цвет и т.д.

Ответ 15

Просто щелкните правой кнопкой мыши на своем проекте в Visual Basic Solution Explorer (где находятся ваши файлы vb) и выберите свойства из меню. В появившемся окне снимите флажок "Включить визуальные стили XP", и теперь, когда вы устанавливаете forecolor, он должен работать сейчас.

Ответ 16

Цитата: Обычно индикатор выполнения или тематический или соблюдает пользовательские настройки цвета. Поэтому для изменения цвета вам нужно отключить визуальные стили и установить ForeColor или самостоятельно нарисовать элемент управления.

Что касается непрерывного стиля вместо блоков, вы можете установить свойство Style:

pBar.Style = ProgressBarStyle.Continuous;

ProgressBarStyle. Непрерывный и блокированный бесполезен при использовании VistualStyles...

Блок будет работать только с отключенными визуальными стилями... что делает все это спорным (в отношении цвета пользовательского прогресса) С отключенными стилями vistual... индикатор выполнения должен быть окрашен на основе forecolor.

Я использовал комбинацию ответа Уильяма Дэниела (с включенными визуальными стилями, поэтому ForeColor будет не просто плоским, без стиля) а также Ответ Барри (на пользовательский текст на панели выполнения): Как разместить текст на ProgressBar?

Ответ 17

Вертикальная панель UP Вниз красным цветом:

using System;
using System.Windows.Forms;
using System.Drawing;



public class VerticalProgressBar : ProgressBar
{


    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.Style |= 0x04;
            return cp;

        }
    }
    private SolidBrush brush = null;

    public VerticalProgressBar()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        if (brush == null || brush.Color != this.ForeColor)
            brush = new SolidBrush(this.ForeColor);

        Rectangle rec = new Rectangle(0, 0, this.Width, this.Height);
        if (ProgressBarRenderer.IsSupported)
        ProgressBarRenderer.DrawVerticalBar(e.Graphics, rec);
        rec.Height = (int)(rec.Height * ((double)Value / Maximum)) - 4;
        rec.Width = rec.Width - 4;
        e.Graphics.FillRectangle(brush, 2, 2, rec.Width, rec.Height);

    } 
}

Ответ 18

Цветная панель прогресса VB.Net, которая отвечает за ответ WXP Visual Styles,...

Я начал с ответа от пользователя user1032613 от 3/17/12. Обратите внимание, что теперь это модуль, а не класс. Оттуда я преобразовал код, но больше было необходимо. В частности, преобразованный код показал функцию DirectCast для преобразования целого числа "state" в тип IntPtr, который не работал.

Imports System.Runtime.InteropServices

Public Module ModifyProgressBarColor

    Private Declare Function SendMessage Lib "User32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long

    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=False)> _
    Private Function SendMessage(hWnd As IntPtr, Msg As UInteger, w As IntPtr, l As IntPtr) As IntPtr
    End Function

    <System.Runtime.CompilerServices.Extension()> _
    Public Sub SetState(pBar As ProgressBar, state As Integer)

        '-- Convert state as integer to type IntPtr
        Dim s As IntPtr
        Dim y As Integer = state
        s = IntPtr.op_Explicit(y)

        '-- Modify bar color
        SendMessage(pBar.Handle, 1040, s, IntPtr.Zero)

    End Sub

End Module

И снова просто вызовите это в используемом коде с помощью этой строки:

Call ModifyProgressBarColor.SetState(prb, 2)

BTW - Я пробовал другие цвета - 0, 4, 5 - все они просто отображались зеленым цветом.

Ответ 19

Я знаю, что он слишком стар, чтобы ответить сейчас.. но все же, небольшая настройка на @Daniel ответ для исправления проблема не показывать индикаторную шкалу с нулевой оценкой. Просто нарисуйте Прогресс только в том случае, если ширина внутреннего прямоугольника не равна нулю.

Спасибо всем вкладчикам.

        public class ProgressBarEx : ProgressBar
        {
            public ProgressBarEx()
            {
                this.SetStyle(ControlStyles.UserPaint, true);
            }

            protected override void OnPaintBackground(PaintEventArgs pevent){}
                // None... Helps control the flicker.                

            protected override void OnPaint(PaintEventArgs e)
            {
                const int inset = 2; // A single inset value to control teh sizing of the inner rect.

                using (Image offscreenImage = new Bitmap(this.Width, this.Height))
                {
                    using (Graphics offscreen = Graphics.FromImage(offscreenImage))
                    {
                        Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);

                        if (ProgressBarRenderer.IsSupported)
                            ProgressBarRenderer.DrawHorizontalBar(offscreen, rect);

                        rect.Inflate(new Size(-inset, -inset)); // Deflate inner rect.
                        rect.Width = (int)(rect.Width * ((double)this.Value / this.Maximum));

                        if (rect.Width != 0)
                        {
                            LinearGradientBrush brush = new LinearGradientBrush(rect, this.ForeColor, this.BackColor, LinearGradientMode.Vertical);
                            offscreen.FillRectangle(brush, inset, inset, rect.Width, rect.Height);
                            e.Graphics.DrawImage(offscreenImage, 0, 0);
                            offscreenImage.Dispose();
                        }
                    }
                }
            }
        }

Ответ 20

Я нашел, что это можно сделать, нарисуя прямоугольник внутри индикатора выполнения и установить его ширину в соответствии с текущим значением прогресса. Я также добавил поддержку прогресса на право налево. Таким образом, вам не нужно использовать изображение, и поскольку Rectnalge.Inflate не вызывается, рисованный прямоугольник меньше.

public partial class CFProgressBar : ProgressBar
{
    public CFProgressBar()
    {
        InitializeComponent();
        this.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaintBackground(PaintEventArgs pevent) { }

    protected override void OnPaint(PaintEventArgs e)
    {
        double scaleFactor = (((double)Value - (double)Minimum) / ((double)Maximum - (double)Minimum));
        int currentWidth = (int)((double)Width * scaleFactor);
        Rectangle rect;
        if (this.RightToLeftLayout)
        {
            int currentX = Width - currentWidth;
            rect = new Rectangle(currentX, 0, this.Width, this.Height);
        }
        else
            rect = new Rectangle(0, 0, currentWidth, this.Height);

        if (rect.Width != 0)
        {
            SolidBrush sBrush = new SolidBrush(ForeColor);
            e.Graphics.FillRectangle(sBrush, rect);
        }
    }
}

Ответ 21

Я думаю, что самые простые решения из всех, это просто быстрое решение, но вы можете удалить, прокомментировать Application.EnableVisualStyles() из Program.cs, или как бы вы ни назвали свою часть, содержащую функцию Main. После этого вы можете свободно менять цвет формы индикатора выполнения с помощью progressBar.ForeColor = Color.TheColorYouDesire;

static void Main()
        {
            //Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
         }

Ответ 22

Edit: в двух миниуях мне потребовалось запустить vs и проверить синтаксис, в котором я был избит с гораздо лучшими ответами. Мне нравится этот сайт.

        progressBar1 = new ProgressBar();
        progressBar1.ForeColor = Color.Red;