Як змінити колір прогресу в 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
Я усвідомлюю, що це старе; і я усвідомлюю, що це ніт (бо Мінімум майже завжди дорівнює нулю); але коефіцієнт шкали ширини повинен бути (((подвійне) Значення - (подвійне) Мінімальне) / ((подвійне) Максимальне - (подвійне) Мінімальне)), щоб бути анально-ретенційно правильним. :)
Jesse Chisholm

122

Добре, мені знадобився час, щоб прочитати всі відповіді та посилання. Ось що я з них отримав:

Зразок результатів

Прийнята відповідь вимикає візуальні стилі, вона дозволяє встановити колір на будь-що, що завгодно, але результат виглядає просто:

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

Тепер, щоб скористатися ним, просто зателефонуйте:

progressBar1.SetState(2);

Зверніть увагу на другий параметр у SetState, 1 = нормальний (зелений); 2 = помилка (червона); 3 = попередження (жовте).

Сподіваюся, це допоможе!


18
Ви створили метод розширення, тому виклик повинен бути progressBar1.SetState (2); крім цього, чудова відповідь!
Едгар Ернандес,

5
Слід зазначити, що це доступно лише на Vista +. Ви можете переглянути повну документацію, шукаючи PBM_SETSTATE .
Джоф

Гарний! Дякую
sapbucket

1
Це дивовижно, але це частково порушує мій прогрес, воно ніколи не заповниться на 100% ....
Норберт Борос

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
Наявність використання блоку та виклику Dispose насправді трохи зайве. Хороша відповідь.
Кевін Стрікер

1
Я усвідомлюю, що це старе; і я усвідомлюю, що це ніт (бо Мінімум майже завжди дорівнює нулю); але коефіцієнт шкали ширини повинен бути (((подвійне) Значення - (подвійне) Мінімальне) / ((подвійне) Максимальне - (подвійне) Мінімальне)), щоб бути анально-ретенційно правильним. :)
Jesse Chisholm

Коли я використовую TextRenderer.DrawText () для малювання тексту на екрані поза екраном, кінцевий результат на екрані виглядає піксельним, а не як мітка із тим самим шрифтом. Малюючи все це безпосередньо на e.Graphics без екранного знімка, ви отримуєте правильний результат ... Хоча якісь ідеї чому?
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

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
Я усвідомлюю, що це старе; і я усвідомлюю, що це ніт (бо Мінімум майже завжди дорівнює нулю); але коефіцієнт шкали ширини повинен бути (((подвійний) Значення - (подвійний) Мінімум) / ((подвійний) Максимум - (подвійний) Мінімум)), щоб бути анально-ретенційно правильним. :)
Jesse Chisholm

Оновлено відповідь із вашою пропозицією.
Джош М.

Я знаю, що він старий, але - цей код помилиться, коли досягне значення 4, через LinearGradientBrushзчитування ширини запису як 0. Найпростішим виправленням є не робити "відступ" 4px в коді, а замість цього розмістити його в панель або що - то з прокладкою (якщо ви хочете кордон) і зробити 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, ...).
Запрацьовано

Я усвідомлюю, що це старе; і я усвідомлюю, що це ніт (бо Мінімум майже завжди дорівнює нулю); але коефіцієнт шкали ширини повинен бути (((подвійний) Значення - (подвійний) Мінімум) / ((подвійний) Максимум - (подвійний) Мінімум)), щоб бути анально-ретенційно правильним. :)
Jesse Chisholm

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: Я думаю, це те, що більшість людей розуміли під червоним. Показуючи стан помилки.
квантовий

3

Зазвичай панель виконання є або тематичною, або з повагою до колірних уподобань користувача. Отже, для зміни кольору вам потрібно або вимкнути візуальні стилі, і встановити, ForeColorабо намалювати управління самостійно.

Що стосується неперервного стилю, то замість блоків ви можете встановити Styleвластивість:

pBar.Style = ProgressBarStyle.Continuous;

2

РЕДАГУВАТИ

За звуками речей, якими ви користуєтесь темою XP, яка має зелений блок на базі прогресу. Спробуйте перетворити свій стиль інтерфейсу на класичний Windows і протестуйте ще раз, але, можливо, вам доведеться реалізувати власну подію 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);

Я помітив, що якщо ви зміните значення смуги (наскільки вона велика), вона не зміниться, якщо вона має інший колір, ніж зелений за замовчуванням. Я взяв код користувача1032613 і додав опцію 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 Solution Explorer (де знаходяться ваші файли vb) і виберіть властивості з меню. У вікні, що з’явиться, зніміть прапорець біля пункту «Увімкнути візуальні стилі XP», і тепер, коли ви встановите попередній колір, він повинен працювати зараз.


0

Јοеу: Цитата: Зазвичай панель виконання є або тематичною, або з повагою до колірних уподобань користувача. Отже, для зміни кольору вам потрібно або вимкнути візуальні стилі, і встановити, ForeColorабо намалювати управління самостійно.

Що стосується неперервного стилю, то замість блоків ви можете встановити Styleвластивість:

pBar.Style = ProgressBarStyle.Continuous;

ProgressBarStyle.Continuous проти 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);

    } 
}

Ви можете пояснити в тексті або в коментарях до коду, як це вирішує проблему.
Гаррісон,

Я розумію, що це ніт (бо Мінімум майже завжди дорівнює нулю); але коефіцієнт шкали висоти повинен бути (((подвійний) Значення - (подвійний) Мінімум) / ((подвійний) Максимум - (подвійний) Мінімум)), щоб бути анально-утримуючим правильним. :)
Jesse Chisholm

0

Кольорова панель прогресу VB.Net, яка відповідає візуальним стилям WXP, - це ...

Я розпочав з відповіді від 'user1032613' 17.03.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)

До речі - я спробував інші кольори - 0, 4, 5 - всі вони просто відображалися зеленим.


0

Я знаю, що його шлях занадто старий, щоб відповісти зараз. Але все-таки невеликий підхід до відповіді @ 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();
                        }
                    }
                }
            }
        }

0

Я виявив, що це можна зробити, намалювавши прямокутник всередині смуги прогресу, та встановити його ширину відповідно до поточного значення прогресу. Я також додав підтримку прогресу справа наліво. Таким чином вам не потрібно використовувати Image, а оскільки 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 = Колір.Червоний; progressBar1.Maximum = 100;
Fusspawn

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

Не маю ідеї, чи це спрацює, але спробуйте прокоментувати Application.EnableVisualThemes (); тобто в одному з попередньо зведених файлів проти генерації (я не можу пригадати, який саме)
Fusspawn

1
Application.EnableVisualStyles () вибачте, не теми
Fusspawn
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.