Bagaimana cara mengubah warna progressbar di C # .NET 3.5?

92

Saya ingin melakukan dua hal di bilah kemajuan saya.

  1. Ubah warna hijau menjadi merah.
  2. Hapus blok dan buat dalam satu warna.

Setiap informasi tentang dua hal yang saya ingin tahu bagaimana mencapainya akan sangat dihargai!

Terima kasih.

Ivan Prodanov
sumber

Jawaban:

83

Karena jawaban sebelumnya tampaknya tidak berfungsi dengan Gaya Visual. Anda mungkin perlu membuat kelas Anda sendiri atau memperluas bilah kemajuan:

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: Kode yang diperbarui untuk membuat bilah kemajuan menggunakan gaya visual untuk latar belakang

Chris Persichetti
sumber
2
Terima kasih untuk ini, itu adalah sesuatu yang dapat saya kerjakan dalam solusi saya.
Irwin
Itu sangat keren, terima kasih. Ini benar-benar membantu saya pada sesuatu yang sedang saya kerjakan saat ini, meskipun saya mengubahnya untuk mengecat ulang seluruh kontrol setiap kali alih-alih hanya area yang ditentukan oleh e.ClipRectangle. Jika tidak, itu tidak mengecat ulang dengan benar setelah hanya sebagian dari kontrol yang dibatalkan oleh jendela lain atau tepi layar.
Matt Blaine
@Matt Blaine: Bisakah Anda memposting modifikasi Anda sebagai edit pada jawabannya? Saya yakin akan ada cukup banyak orang yang tertarik dengan solusi lengkap Anda.
Marek
@Marek Baru saja memperhatikan komentar Anda. Saya tidak memiliki cukup perwakilan untuk mengedit jawabannya, jadi saya memposting milik saya sendiri. Terima kasih. stackoverflow.com/questions/778678/…
Matt Blaine
3
Saya menyadari ini sudah tua; dan saya menyadari ini adalah nit (karena Minimum hampir selalu nol); tetapi faktor skala Lebar harus (((ganda) Nilai - (ganda) Minimum) / ((ganda) Maksimum - (ganda) Minimum)) agar anal-retentif benar. :)
Jesse Chisholm
122

Oke, saya butuh beberapa saat untuk membaca semua jawaban dan tautan. Inilah yang saya dapatkan dari mereka:

Hasil Sampel

Jawaban yang diterima menonaktifkan gaya visual, itu memungkinkan Anda untuk mengatur warna ke apapun yang Anda inginkan, tetapi hasilnya terlihat biasa:

masukkan deskripsi gambar di sini

Dengan menggunakan metode berikut, Anda bisa mendapatkan sesuatu seperti ini:

masukkan deskripsi gambar di sini

Bagaimana caranya

Pertama, sertakan ini jika Anda belum: using System.Runtime.InteropServices;

Kedua, Anda dapat membuat kelas baru ini, atau memasukkan kodenya ke dalam statickelas non-generik yang sudah ada :

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

Sekarang, untuk menggunakannya, cukup panggil:

progressBar1.SetState(2);

Perhatikan parameter kedua di SetState, 1 = normal (hijau); 2 = kesalahan (merah); 3 = peringatan (kuning).

Semoga membantu!

pengguna1032613
sumber
18
Anda membuat metode ekstensi, jadi panggilannya harus progressBar1.SetState (2); selain itu, jawaban yang bagus!
Edgar Hernandez
5
Perlu dicatat bahwa ini hanya tersedia di Vista +. Anda dapat melihat dokumentasi lengkap dengan mencari PBM_SETSTATE .
Djof
Cantik! Terima kasih
sapbucket
1
Ini luar biasa, tetapi ini merusak bilah kemajuan saya sebagian, tidak akan pernah terisi 100% ....
Norbert Boros
1
public const uint PBM_SETSTATE = 0x0410; // 1040
Andrei Krasutski
37

Ini adalah versi bebas-flicker dari kode yang paling diterima yang dapat Anda temukan sebagai jawaban atas pertanyaan ini. Semua penghargaan untuk poster jawaban fatastic itu. Terima kasih Dusty, Chris, Matt, dan Josh!

Seperti permintaan "Fueled" di salah satu komentar, saya juga membutuhkan versi yang berperilaku sedikit lebih ... profesional. Kode ini mempertahankan gaya seperti pada kode sebelumnya, tetapi menambahkan render gambar di luar layar dan buffering grafik (dan membuang objek grafik dengan benar).

Hasilnya: semua bagus, dan tidak ada flicker. :)

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);
            }
        }
    }
}
William Daniel
sumber
Nah ini yang paling dekat dengan implemantasi asli dari Microsoft.
Yakup Ünyılmaz
1
Memiliki blok penggunaan dan pemanggilan Buang sebenarnya sedikit berlebihan. Jawaban yang bagus.
Kevin Stricker
1
Saya menyadari ini sudah tua; dan saya menyadari ini adalah nit (karena Minimum hampir selalu nol); tetapi faktor skala Lebar harus (((ganda) Nilai - (ganda) Minimum) / ((ganda) Maksimum - (ganda) Minimum)) agar anal-retentif benar. :)
Jesse Chisholm
Saat saya menggunakan TextRenderer.DrawText () untuk menggambar teks ke dalam gambar di luar layar, hasil akhir di layar terlihat berpiksel, dan tidak seperti label yang menggunakan font yang sama persis. Menggambar semua ini langsung ke e.Graphics tanpa offscreenimager memberikan hasil yang benar ... Ada ide mengapa?
CuriousGeorge
1
Ya, saya memang mencoba blitting tanpa skala. Akhirnya, saya baru saja beralih ke WPF, jadi semua yang saya butuhkan sudah ada di
dalamnya
28

Di desainer, Anda hanya perlu menyetel properti ForeColor ke warna apa pun yang Anda inginkan. Dalam kasus Merah, ada warna yang telah ditentukan sebelumnya.

Untuk melakukannya dalam kode (C #) lakukan ini:

pgs.ForeColor = Color.Red;

Edit : Oh ya, juga atur Style ke kontinu. Dalam kode, seperti ini:

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

Edit Lain: Anda juga harus menghapus baris yang terbaca Application.EnableVisualStyles()dari Anda Program.cs(atau serupa). Jika Anda tidak dapat melakukan ini karena Anda ingin aplikasi lainnya memiliki gaya visual, saya sarankan untuk mengecat sendiri kontrolnya atau beralih ke WPF karena hal semacam ini mudah dilakukan dengan WPF. Anda dapat menemukan tutorial tentang pemilik yang menggambar bilah kemajuan di codeplex

dustyburwell
sumber
3
Warna depan = merah; Warna belakang = biru; Style = Bersambung. Tidak ada yang berubah, tetap seperti saya tidak pernah menyentuhnya
Ivan Prodanov
3
bah ... oke, saya melihat masalahnya. Anda perlu menonaktifkan gaya visual agar ini berfungsi dengan properti. Ini mungkin melukis menggunakan tema apa pun yang Anda pilih. Di Program.cs ada baris yang bertuliskan Application.EnableVisualStyles (). Hapus garis itu dan ini akan berhasil. Jika tidak, Anda harus mengecat kontrol itu sendiri. Opsi lainnya adalah menggunakan WPF (jika memungkinkan), karena ini memungkinkan Anda melakukan hal-hal semacam ini dengan sangat mudah.
dustyburwell
Tolong beri saya informasi lebih lanjut tentang "Cara melukis sendiri".
Ivan Prodanov
1
Berikut adalah tutorial tentang pemilik menggambar bilah kemajuan. Prosesnya terlalu rumit untuk membuat komentar. codeproject.com/KB/cpp/VistaProgressBar.aspx
dustyburwell
1
Sayang sekali Application.EnableVisualStyles () adalah bagian penting dari solusi ini. Sayangnya ini merusak semua gaya lainnya.
mr.user1065741
16

Menggunakan jawaban Matt Blaine dan Chris Persichetti, saya telah membuat bilah kemajuan yang terlihat sedikit lebih bagus sambil memungkinkan pilihan warna tak terbatas (pada dasarnya saya mengubah satu baris dalam solusi 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);
        }
    }
}

Pemakaian:

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

Hasil

Anda dapat menggunakan gradien apa pun yang Anda suka!

Unduh

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

Josh M.
sumber
2
Saya menyadari ini sudah tua; dan saya menyadari ini adalah nit (karena Minimum hampir selalu nol); tetapi faktor skala Lebar harus (((ganda) Nilai - (ganda) Minimum) / ((ganda) Maksimum - (ganda) Minimum)) agar anal-retentif benar. :)
Jesse Chisholm
Memperbarui jawaban dengan saran Anda.
Josh M.
Saya tahu ini sudah lama, tetapi - kode ini akan salah setelah mencapai nilai 4, karena LinearGradientBrushmembaca lebar rekam sebagai 0. Perbaikan termudah adalah dengan tidak melakukan "pengisi" 4px dalam kode dan sebagai gantinya menempatkannya di panel atau sesuatu dengan bantalan (jika Anda ingin perbatasan) dan membuat rec.Width = (int)((rec.Width * scaleFactor) - 4)menjadirec.Width = (int)(rec.Width * scaleFactor) + 1
MiDri
14

Modifikasi jawaban dustyburwell. (Saya tidak memiliki cukup perwakilan untuk mengeditnya sendiri.) Seperti jawabannya, ini berfungsi dengan "Gaya Visual" diaktifkan. Anda bisa menyetel properti ForeColor bilah kemajuan dalam tampilan desain bentuk apa pun.

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);
    }
}
Matt Blaine
sumber
Ini berfungsi baik untuk mengubah warna latar depan, tetapi sering berkedip, sedangkan kontrol ProgressBar default tidak. Ada ide untuk mengatasi ini?
Dipicu
4
Saya telah menemukan cara mengatasi kedipan: tambahkan buffering ganda ke ControlStyles dari ProgressBar yang ditentukan pengguna, seperti ini: SetStyle (ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, ...).
Dipicu
Saya menyadari ini sudah tua; dan saya menyadari ini adalah nit (karena Minimum hampir selalu nol); tetapi faktor skala Lebar harus (((ganda) Nilai - (ganda) Minimum) / ((ganda) Maksimum - (ganda) Minimum)) agar anal-retentif benar. :)
Jesse Chisholm
5

Saya hanya memasukkan ini ke dalam kelas statis.

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

Semoga membantu,

Marc

Marc
sumber
+1: Saya rasa ini yang kebanyakan orang maksud dengan merah. Membuatnya menunjukkan status kesalahan.
kuantum
3

Biasanya bilah kemajuan bertema atau menghormati preferensi warna pengguna. Jadi untuk mengubah warna Anda perlu mematikan gaya visual dan mengaturnyaForeColor atau menggambar kontrol sendiri.

Sedangkan untuk gaya berkelanjutan sebagai ganti blok Anda dapat mengatur Styleproperti:

pBar.Style = ProgressBarStyle.Continuous;
Joey
sumber
2

EDIT

Dengan suara hal-hal yang Anda gunakan Tema XP yang memiliki prog-bar berbasis blok hijau. Coba balikkan Gaya UI Anda ke Windows Classic dan uji lagi, tetapi Anda mungkin perlu mengimplementasikan acara OnPaint Anda sendiri untuk membuatnya melakukan apa yang Anda inginkan di semua Gaya UI

Atau seperti yang ditunjukkan orang lain, nonaktifkan VisualStyles untuk aplikasi Anda.

Asli

Sejauh yang saya tahu, rendering bilah Kemajuan terjadi sesuai dengan gaya tema windows yang Anda pilih (win2K, xp, vista)

Anda dapat mengubah warna dengan mengatur properti

ProgressBar.ForeColor

Saya tidak yakin Anda dapat melakukan lebih banyak lagi namun ...

melakukan googling

Ada artikel di sini dari MS KB tentang membuat bilah kemajuan "Mulus"

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

Eoin Campbell
sumber
@ Eion, Forecolor = merah; Warna belakang = biru; Gaya = Bersambung. Tidak ada yang berubah, tetap seperti saya tidak pernah menyentuhnya.
Ivan Prodanov
2

Semua metode ini gagal berfungsi untuk saya, tetapi metode ini memungkinkan Anda mengubahnya menjadi string warna.

Harap dicatat bahwa saya menemukan kode ini dari tempat lain di StackOverflow dan mengubahnya sedikit. Sejak saat itu saya lupa di mana saya menemukan kode ini dan saya tidak dapat menautkannya karena itu jadi maaf untuk itu.

Tapi bagaimanapun saya berharap kode ini membantu seseorang itu benar-benar membantu saya.

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

Di mana nama "ProgressBar" digunakan, ganti dengan nama bilah kemajuan Anda sendiri. Anda juga dapat memicu peristiwa ini dengan argumen lain, cukup pastikan tanda kurung dalamnya di suatu tempat.

EpicNinjaCheese
sumber
Kerja bagus .. Saya menggunakan acara ProgressChanged di dalam acara untuk beralih dari terang ke gelap ... +1
BENN1TH
2

Ubah Colordan Value(perubahan instan)

Letakkan using System.Runtime.InteropServices;di atas ...

Telepon dengan ColorBar.SetState(progressBar1, ColorBar.Color.Yellow, myValue);

Saya perhatikan bahwa jika Anda mengubah nilai bilah (seberapa besar) maka itu tidak akan berubah jika dalam warna selain hijau default. Saya mengambil kode user1032613 dan menambahkan opsi Nilai.

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
    }

}
Sparfy
sumber
2
Kami harus membalik pBar.Value = pBar.Maximum;dan SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);masuk ke dalam kondisi-tubuh untuk menunjukkan warna baru yang benar.
DomTheDeveloper
1

Untuk berjaga-jaga jika ada yang mencari opsi lain .... Anda dapat memperluas Panel, menggunakannya sebagai latar belakang (putih atau apa pun), tambahkan Panel lain di dalamnya untuk latar depan (bilah bergerak). Kemudian Anda memiliki kontrol total untuk mengubah warna, dll.

Eduardo
sumber
1

Cukup klik kanan pada proyek Anda di Visual Basic Solution Explorer (tempat file vb Anda) dan pilih properti dari menu. Pada jendela yang muncul hapus pilihan "Aktifkan XP Visual Styles" dan sekarang ketika Anda mengatur warna depan, itu harus bekerja sekarang.

Randy
sumber
0

Јοеу: Quote: Biasanya progress bar baik bertema atau menghormati preferensi warna pengguna. Jadi untuk mengubah warna Anda perlu mematikan gaya visual dan mengatur ForeColoratau menggambar kontrol sendiri.

Sedangkan untuk gaya berkelanjutan sebagai ganti blok Anda dapat mengatur Styleproperti:

pBar.Style = ProgressBarStyle.Continuous;

ProgressBarStyle.Continuous versus Blocks tidak berguna dengan VistualStyles diaktifkan ...

Blok (s) hanya akan bekerja dengan gaya visual dinonaktifkan ... yang menjadikan semua ini titik diperdebatkan (berkaitan dengan warna kemajuan kustom) Dengan gaya visual dinonaktifkan ... bilah kemajuan harus diwarnai berdasarkan warna depan.

Saya menggunakan kombinasi jawaban William Daniel (dengan gaya visual yang diaktifkan, sehingga Warna Depan tidak hanya akan datar tanpa gaya) dan jawaban Barry (untuk teks kustom di bilah kemajuan) dari: Bagaimana cara meletakkan teks di ProgressBar?

NeoH4x0r
sumber
0

Vertical Bar UP Untuk Down dengan warna merah:

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

    } 
}
Mandrova
sumber
Bisakah Anda menjelaskan baik dalam teks atau dalam komentar ke kode bagaimana ini menyelesaikan masalah.
Harrison
Saya menyadari ini adalah nit (karena Minimum hampir selalu nol); tetapi faktor skala Tinggi harus (((ganda) Nilai - (ganda) Minimum) / ((ganda) Maksimum - (ganda) Minimum)) agar anal-retentif benar. :)
Jesse Chisholm
0

Bilah kemajuan berwarna VB.Net yang mengikuti jawaban Gaya Visual WXP adalah ...

Saya mulai dengan jawaban dari 'user1032613' pada 3/17/12. Perhatikan bahwa ini sekarang menjadi Module, bukan kelas. Dari sana saya mengubah kode tetapi lebih banyak yang dibutuhkan. Secara khusus kode yang dikonversi menunjukkan fungsi DirectCast untuk mengubah integer 'state' menjadi jenis IntPtr yang tidak berfungsi.

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

Dan sekali lagi panggil ini dalam menggunakan kode dengan baris ini:

Call ModifyProgressBarColor.SetState(prb, 2)

BTW - Saya mencoba warna lain - 0, 4, 5 - semuanya hanya menampilkan warna hijau.

DanW52
sumber
0

Saya tahu caranya terlalu tua untuk dijawab sekarang .. tapi tetap saja, sedikit perubahan pada jawaban @ Daniel untuk memperbaiki masalah tidak menunjukkan bilah kemajuan bernilai nol. Gambar saja Progress hanya jika lebar persegi panjang bagian dalam ternyata bukan nol.

Terima kasih untuk semua kontributor.

        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();
                        }
                    }
                }
            }
        }
Divins Mathew
sumber
0

Saya menemukan ini dapat dilakukan dengan menggambar persegi panjang di dalam bilah kemajuan, dan untuk mengatur lebarnya sesuai dengan nilai kemajuan saat ini. Saya juga menambahkan dukungan untuk kemajuan dari kanan ke kiri. Dengan cara ini Anda tidak perlu menggunakan Image, dan karena Rectnalge.Inflate tidak disebut persegi panjang yang digambar lebih kecil.

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);
        }
    }
}
ZOK
sumber
0

Saya pikir solusi paling sederhana dari semuanya, itu hanya perbaikan cepat, tetapi Anda dapat menghapus, mengomentari Application.EnableVisualStyles () dari Program.cs, atau bagaimanapun Anda memberi nama bagian Anda yang berisi fungsi Utama. Setelah itu Anda dapat dengan bebas mengubah warna dari bilah kemajuan dengan progressBar.ForeColor = Color.TheColorYouDesire;

static void Main()
        {
            //Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
         }
Mladen Tasevski
sumber
-5

Sunting: dalam dua menit yang saya butuhkan untuk menjalankan vs dan memeriksa sintaks saya dipukuli dengan respons yang jauh lebih baik. saya suka situs ini

        progressBar1 = new ProgressBar();
        progressBar1.ForeColor = Color.Red;
Fusspawn
sumber
2
Tidak berfungsi, tetap kosong sekarang, saya menambahkan progressBar1.value = 50, tetapi masih kosong
Ivan Prodanov
mencoba mengatur nilai maxiumum? progressBar1 = baru ProgressBar (); progressBar1.ForeColor = Color.Red; progressBar1.Maximum = 100;
Fusspawn
2
Tidak, masalahnya ada pada tema windows saya.
Ivan Prodanov
Tidak tahu apakah ini akan berhasil, tetapi coba komentari Application.EnableVisualThemes (); yang ada di salah satu file prebuilt vs generate (saya tidak ingat yang mana)
Fusspawn
1
Application.EnableVisualStyles () maaf bukan tema
Fusspawn