Как изменить цвет индикатора выполнения в C # .NET 3.5?


92

Я хочу сделать две вещи на моем индикаторе выполнения.

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

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

Спасибо.

Ответы:


83

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

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);
    }
}

РЕДАКТИРОВАТЬ: обновлен код, чтобы индикатор выполнения использовал визуальный стиль для фона.


2
Спасибо за это, это было то, с чем я мог бы работать в своем решении.
Ирвин,

Это действительно круто, спасибо. Это действительно помогло мне над тем, над чем я сейчас работаю, хотя я изменил его, чтобы каждый раз перерисовывать весь элемент управления, а не только область, указанную e.ClipRectangle. В противном случае он не перерисовывался правильно после того, как только часть элемента управления была аннулирована другим окном или краем экрана.
Мэтт Блейн,

@Matt Blaine: Не могли бы вы опубликовать свою модификацию как правку к ответу? Я верю, что вашим полным решением будет достаточно людей.
Марек

@Marek Только что заметил ваш комментарий. У меня недостаточно репутации, чтобы отредактировать ответ, поэтому я опубликовал свой собственный. Спасибо. stackoverflow.com/questions/778678/…
Мэтт Блейн

3
Я понимаю, что это старое; и я понимаю, что это гнида (потому что Minimum почти всегда равен нулю); но масштабный коэффициент ширины должен быть (((double) Value - (double) Minimum) / (((double) Maximum - (double) Minimum)), чтобы быть анально правильным. :)
Джесси Чизхолм

122

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

Образцы результатов

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

введите описание изображения здесь

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

введите описание изображения здесь

Как

Сначала включите это, если у вас нет: 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);
    }
}

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

progressBar1.SetState(2);

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

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


18
Вы создали метод расширения, поэтому вызов должен быть progressBar1.SetState (2); Кроме того, отличный ответ!
Эдгар Эрнандес

5
Следует отметить, что это доступно только в Vista +. Вы можете просмотреть полную документацию, выполнив поиск по PBM_SETSTATE .
Djof 01

Красивая! Спасибо
sapbucket

1
Это потрясающе, но это частично нарушает мою
Норберт Борос

1
public const uint PBM_SETSTATE = 0x0410; // 1040
Андрей Красуцкий

37

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

Как и запрос "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);
            }
        }
    }
}

Что ж, это наиболее близкая к оригинальной реализации от Microsoft.
Yakup Ünyılmaz

1
Наличие блока using и вызова Dispose на самом деле немного избыточно. Хотя отличный ответ.
Кевин Стрикер

1
Я понимаю, что это старое; и я понимаю, что это гнида (потому что Minimum почти всегда равен нулю); но масштабный коэффициент ширины должен быть (((double) Value - (double) Minimum) / (((double) Maximum - (double) Minimum)), чтобы быть анально правильным. :)
Джесси Чизхолм

Когда я использую TextRenderer.DrawText () для рисования текста вне экрана, конечный результат на экране выглядит пиксельным, а не как метка с использованием того же шрифта. Рисование всего этого непосредственно в e.Graphics без offscreenimager дает правильный результат ... Есть идеи, почему?
CuriousGeorge

1
Да, я пробовал немасштабированный блиттинг. Наконец, я просто перешел на WPF, поэтому все, что мне нужно, просто встроено.
CuriousGeorge

28

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

Чтобы сделать это в коде (C #), сделайте следующее:

pgs.ForeColor = Color.Red;

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

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

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


3
Forecolor = красный; Цвет фона = синий; Стиль = Непрерывный. Ничего не изменилось, он остался, как будто я его никогда не трогал
Иван Проданов

3
бах ... ладно, я вижу проблему. Вам необходимо отключить визуальные стили, чтобы это работало со свойствами. Вероятно, это рисование с использованием выбранной вами темы. В Program.cs есть строка, которая читает Application.EnableVisualStyles (). Удалите эту строку, и это сработает. В противном случае вам придется раскрасить элемент управления самостоятельно. Другой вариант - использовать WPF (если это возможно), поскольку он позволяет очень легко делать подобные вещи.
Dustyburwell

Пожалуйста, дайте мне больше информации о том, "Как нарисовать самому".
Иван Проданов

1
Вот учебник, как владелец рисует индикатор выполнения. Процесс слишком сложен для комментария. codeproject.com/KB/cpp/VistaProgressBar.aspx
Dustyburwell,

1
Жаль, что Application.EnableVisualStyles () является ключевой частью этого решения. К сожалению, это нарушает все остальные стили.
mr.user1065741 08

16

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

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);

Полученные результаты

Вы можете использовать любой градиент, который вам нравится!

Скачать

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


2
Я понимаю, что это старое; и я понимаю, что это гнида (потому что Minimum почти всегда равен нулю); но масштабный коэффициент ширины должен быть (((double) Value - (double) Minimum) / (((double) Maximum - (double) Minimum)), чтобы быть анально правильным. :)
Джесси Чизхолм

Обновил ответ с вашим предложением.
Джош М.

Я знаю, что он старый, но - этот код выдаст ошибку, как только достигнет значения 4 из-за LinearGradientBrushсчитывания ширины записи как 0. Самое простое решение - не выполнять "отступы" в 4 пикселя в коде, а вместо этого поместить его в панель или что-то еще с отступом (если вам нужна граница) и превращением rec.Width = (int)((rec.Width * scaleFactor) - 4)вrec.Width = (int)(rec.Width * scaleFactor) + 1
MiDri

14

Изменение ответа Дыбурвелла. (У меня недостаточно репутации, чтобы отредактировать его сам.) Как и его ответ, он работает с включенными «Визуальными стилями». Вы можете просто установить свойство 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);
    }
}

Это отлично подходит для изменения цвета переднего плана, но он сильно мерцает, тогда как элемент управления ProgressBar по умолчанию - нет. Есть идеи, как это решить?
Заправлен

4
Я выяснил, как решить проблему мерцания: добавьте двойную буферизацию в ControlStyles определяемого пользователем ProgressBar, например: SetStyle (ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, ...).
Заправлен

Я понимаю, что это старое; и я понимаю, что это гнида (потому что Minimum почти всегда равен нулю); но масштабный коэффициент ширины должен быть (((double) Value - (double) Minimum) / (((double) Maximum - (double) Minimum)), чтобы быть анально правильным. :)
Джесси Чизхолм

5

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

  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);
  } 

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

Марк


+1: Я думаю, это то, что большинство людей имели в виду под красным. Отображение состояния ошибки.
Quant

3

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

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

pBar.Style = ProgressBarStyle.Continuous;

2

РЕДАКТИРОВАТЬ

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

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

Оригинал

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

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

ProgressBar.ForeColor

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

гуглит

Здесь есть статья из MS KB о создании «плавного» индикатора выполнения.

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


@ Eion, Forecolor = красный; Цвет фона = синий; Стиль = Непрерывный. Ничего не изменилось, он остался, как будто я его никогда не касался.
Иван Проданов


2

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

Обратите внимание, что я нашел этот код где-то еще на 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», замените его собственным именем индикатора выполнения. Вы также можете вызвать это событие с другими аргументами, просто убедитесь, что оно где-то внутри скобок.


хорошая работа .. Я использую внутри события ProgressChanged, чтобы переходить от светлого к темному ... +1
BENN1TH

2

Изменить 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
    }

}

2
Нам пришлось перевернуть pBar.Value = pBar.Maximum;и SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);внутри тела условия, чтобы прогресс показал правильный новый цвет.
DomTheDeveloper

1

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


1

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


0

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

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

pBar.Style = ProgressBarStyle.Continuous;

ProgressBarStyle.Continuous vs. Blocks бесполезен с включенным VistualStyles ...

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

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


0

Вертикальная полоса ВВЕРХ для Вниз красного цвета:

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);

    } 
}

Не могли бы вы объяснить в тексте или в комментариях к коду, как это решает проблему.
Харрисон

Я понимаю, что это гнида (потому что Minimum почти всегда равен нулю); но коэффициент масштабирования по высоте должен быть (((double) Value - (double) Minimum) / (((double) Maximum - (double) Minimum)), чтобы быть анально правильным. :)
Джесси Чизхолм

0

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

Я начал с ответа пользователя user1032613 от 17.03.12. Обратите внимание, что теперь это модуль, а не класс. Оттуда я преобразовал код, но требовалось больше. В частности, преобразованный код показал функцию DirectCast для преобразования целого числа «состояния» в тип 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

И снова просто вызовите это в коде using в этой строке:

Call ModifyProgressBarColor.SetState(prb, 2)

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


0

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

Спасибо всем участникам.

        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();
                        }
                    }
                }
            }
        }

0

Я обнаружил, что это можно сделать, нарисовав прямоугольник внутри индикатора выполнения и установив его ширину в соответствии с текущим значением прогресса. Я также добавил поддержку прогресса справа налево. Таким образом, вам не нужно использовать изображение, и поскольку 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);
        }
    }
}

0

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

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

-5

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

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

2
Не работает, сейчас пусто, я добавил progressBar1.value = 50, но все равно пусто
Иван Проданов

пробовали установить максимальное значение? progressBar1 = новый ProgressBar (); progressBar1.ForeColor = Color.Red; progressBar1.Maximum = 100;
Fusspawn

2
Нет, проблема в моей теме Windows.
Иван Проданов

Не знаю, сработает ли это, но попробуйте закомментировать Application.EnableVisualThemes (); это находится в одном из предварительно созданных файлов vs generate (я не могу вспомнить, какой именно)
Fusspawn

1
Application.EnableVisualStyles () извините, не темы
Fusspawn
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.