C # .NET 3.5'te ilerleme çubuğunun rengi nasıl değiştirilir?


92

İlerleme çubuğumda iki şey yapmak istiyorum.

  1. Yeşil rengi kırmızı olarak değiştirin.
  2. Blokları çıkarın ve tek renk yapın.

Nasıl başaracağımı merak ettiğim bu iki şey hakkında herhangi bir bilgi çok takdir edilecek!

Teşekkürler.

Yanıtlar:


83

Önceki cevaplar Görsel Stiller ile uyumlu görünmüyor. Muhtemelen kendi sınıfınızı oluşturmanız veya ilerleme çubuğunu genişletmeniz gerekecek:

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

DÜZENLEME: İlerleme çubuğunun arka plan için görsel stili kullanması için güncellenmiş kod


2
Bunun için teşekkürler, çözümümde çalışabileceğim bir şeydi.
Irwin

Bu gerçekten harika, teşekkürler. Şu anda üzerinde çalıştığım bir şey üzerinde bana gerçekten yardımcı oldu, ancak e.ClipRectangle tarafından belirtilen alan yerine her seferinde tüm kontrolü yeniden boyamak için değiştirdim. Aksi takdirde, kontrolün yalnızca bir kısmı başka bir pencere veya ekranın kenarı tarafından geçersiz kılındıktan sonra doğru şekilde yeniden boyanmadı.
Matt Blaine

@Matt Blaine: Lütfen değişikliğinizi yanıta bir düzenleme olarak gönderebilir misiniz? Tam çözümünüzle ilgilenen yeterince insan olacağına inanıyorum.
Marek

@Marek Yorumunuzu az önce fark ettim. Cevabı düzenlemek için yeterli temsilcim yok, bu yüzden kendi sayımı gönderdim. Teşekkürler. stackoverflow.com/questions/778678/…
Matt Blaine

3
Bunun eski olduğunun farkındayım; ve bunun bir nit olduğunu anlıyorum (çünkü Minimum neredeyse her zaman sıfırdır); ancak Genişlik ölçek faktörünün anal kalıcı olarak doğru olması için (((double) Value - (double) Minimum) / ((double) Maximum - (double) Minimum)) olması gerekir. :)
Jesse Chisholm

122

Tamam, tüm cevapları ve bağlantıları okumam biraz zaman aldı. İşte onlardan elde ettiğim şey:

Örnek Sonuçlar

Kabul edilen cevap görsel stilleri devre dışı bırakır, rengi istediğiniz herhangi bir şeye ayarlamanıza izin verir, ancak sonuç sade görünür:

görüntü açıklamasını buraya girin

Aşağıdaki yöntemi kullanarak bunun yerine şuna benzer bir şey elde edebilirsiniz:

görüntü açıklamasını buraya girin

Nasıl

İlk olarak, yapmadıysanız bunu ekleyin: using System.Runtime.InteropServices;

İkincisi, bu yeni sınıfı oluşturabilir veya kodunu mevcut staticgenel olmayan bir sınıfa koyabilirsiniz :

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

Şimdi, kullanmak için şunu arayın:

progressBar1.SetState(2);

SetState'teki ikinci parametreye dikkat edin, 1 = normal (yeşil); 2 = hata (kırmızı); 3 = uyarı (sarı).

Umarım yardımcı olur!


18
Bir uzantı yöntemi oluşturdunuz, bu nedenle çağrı progressBar1.SetState (2) olmalıdır; bunun yanında, Harika cevap!
Edgar Hernandez

5
Bunun yalnızca Vista + 'da mevcut olduğu unutulmamalıdır. PBM_SETSTATE'i arayarak tüm belgeleri görüntüleyebilirsiniz .
Djof

Güzel! Teşekkür ederim
sapbucket

1
Bu harika, ancak ilerleme çubuğumu kısmen kırıyor, asla% 100
dolmayacak

1
public const uint PBM_SETSTATE = 0x0410; // 1040
Andrei Krasutski

37

Bu, bu soruya yanıt olarak bulabileceğiniz en çok kabul gören kodun kırpışmasız bir sürümüdür. Tüm o saçma cevapların afişlerine itibar edin. Dusty, Chris, Matt ve Josh'a teşekkürler!

Yorumlardan birindeki "Fueled" 'in isteği gibi, biraz daha profesyonel davranan bir sürüme de ihtiyacım vardı. Bu kod stilleri önceki kodda olduğu gibi korur, ancak ekran dışı bir görüntü oluşturma ve grafik ara belleğe alma ekler (ve grafik nesnesini uygun şekilde atar).

Sonuç: her şey yolunda ve titreme yok. :)

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

Bu, Microsoft'tan orijinal uygulamaya en yakın olanıdır.
Yakup Ünyılmaz

1
Bir kullanım bloğuna sahip olmak ve Dispose çağırmak aslında biraz gereksizdir. Yine de harika cevap.
Kevin Stricker

1
Bunun eski olduğunun farkındayım; ve bunun bir nit olduğunu anlıyorum (çünkü Minimum neredeyse her zaman sıfırdır); ancak Genişlik ölçek faktörünün anal kalıcı olarak doğru olması için (((double) Value - (double) Minimum) / ((double) Maximum - (double) Minimum)) olması gerekir. :)
Jesse Chisholm

TextRenderer.DrawText () 'i ekran dışı görüntüye metin çizmek için kullandığımda, ekrandaki nihai sonuç piksel şeklinde görünüyor ve aynı yazı tipini kullanan bir etiket gibi görünmüyor. Tüm bunları ekran dışı görüntüleyici olmadan doğrudan e.Graphics'e çekmek doğru sonucu verir ... Herhangi bir fikriniz neden?
CuriousGeorge

1
Evet, ölçüsüz blitting yapmayı denedim. Son olarak,
WPF'ye

28

Tasarımcıda, ForeColor özelliğini istediğiniz renge ayarlamanız yeterlidir. Kırmızı durumunda, bunun için önceden tanımlanmış bir renk var.

Kodda (C #) yapmak için şunu yapın:

pgs.ForeColor = Color.Red;

Düzenleme : Oh evet, ayrıca Stili sürekli olarak ayarlayın. Kodda, şöyle:

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

Başka Bir Düzenleme: Ayrıca Application.EnableVisualStyles()sizden Program.cs(veya benzerinden) okunan satırı kaldırmanız gerekir . Bunu yapamıyorsanız, uygulamanın geri kalanının görsel stillere sahip olmasını istiyorsanız, kontrolü kendiniz boyamanızı veya WPF'ye geçmenizi öneririm çünkü bu tür şeyler WPF ile kolaydır. Codeplex'te bir ilerleme çubuğu çizen sahip hakkında bir eğitim bulabilirsiniz.


3
Ön renk = kırmızı; Arka renk = mavi; Stil = Sürekli. Ben bunu hiç dokunmadım gibi bir şey, onun kaldıkları değişti
Ivan Prodanov

3
bah ... tamam, sorunu görüyorum. Bunun özelliklerle çalışması için görsel stilleri devre dışı bırakmanız gerekir. Muhtemelen seçtiğiniz temayı kullanarak boyuyordur. Program.cs içinde Application.EnableVisualStyles () yazan bir satır vardır. Bu satırı kaldırın ve bu işe yarayacaktır. Aksi takdirde, kontrolü kendiniz boyamanız gerekir. Diğer seçenek, WPF'yi kullanmaktır (eğer bir olasılıksa), çünkü bu tür şeyleri gerçekten kolayca yapmanıza izin verir.
dustyburwell

Lütfen bana "Kendim nasıl boyayabilirim" hakkında daha fazla bilgi verin.
Ivan Prodanov

1
İşte sahibinin bir ilerleme çubuğu çizmesiyle ilgili bir eğitim. Süreç, bir yorum için çok fazla karmaşık. codeproject.com/KB/cpp/VistaProgressBar.aspx
dustyburwell

1
Utanç verici bir Uygulama.EnableVisualStyles (), bu çözümün anahtar kısmıdır. Maalesef bu diğer tüm stilleri bozuyor.
mr.user1065741

16

Matt Blaine ve Chris Persichetti'nin yanıtlarını kullanarak, sonsuz renk seçimine izin verirken biraz daha hoş görünen bir ilerleme çubuğu oluşturdum (temelde Matt'in çözümünde bir satırı değiştirdim):

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

Kullanım:

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

Sonuçlar

İstediğiniz herhangi bir gradyanı kullanabilirsiniz!

İndir

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


2
Bunun eski olduğunun farkındayım; ve bunun bir nit olduğunu anlıyorum (çünkü Minimum neredeyse her zaman sıfırdır); ancak Genişlik ölçek faktörünün anal kalıcı olarak doğru olması için (((double) Value - (double) Minimum) / ((double) Maximum - (double) Minimum)) olması gerekir. :)
Jesse Chisholm

Cevabı önerinizle güncellendi.
Josh M.

Eski olduğunu biliyorum, ancak - bu kod, kayıt LinearGradientBrushgenişliğini 0 olarak okuduğu için 4 değerine ulaştığında hata verecektir . bir panel veya dolgu içeren bir şey (kenarlık istiyorsanız) ve rec.Width = (int)((rec.Width * scaleFactor) - 4)içine girmerec.Width = (int)(rec.Width * scaleFactor) + 1
MiDri

14

Dustyburwell'in cevabına Modificaton. (Kendim düzenlemek için yeterli temsilcim yok.) Cevabı gibi, "Görsel Stiller" etkinken çalışıyor. İlerleme çubuğunun ForeColor özelliğini formun tasarım görünümü ne olursa olsun ayarlayabilirsiniz.

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

Bu, ön plan rengini değiştirmek için harika çalışır, ancak varsayılan ProgressBar denetimi yapmazken çok fazla titreşir. bunu nasıl çözeceğimize dair bir fikri olan?
Yakıtlı

4
Titremeyi nasıl çözeceğimi öğrendim: kullanıcı tanımlı ProgressBar'ın ControlStyles'ına şu şekilde çift arabelleğe alma ekleyin: SetStyle (ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, ...).
Yakıtlı

Bunun eski olduğunun farkındayım; ve bunun bir nit olduğunu anlıyorum (çünkü Minimum neredeyse her zaman sıfırdır); ancak Genişlik ölçek faktörünün anal kalıcı olarak doğru olması için (((double) Value - (double) Minimum) / ((double) Maximum - (double) Minimum)) olması gerekir. :)
Jesse Chisholm

5

Bunu sadece statik bir sınıfa koydum.

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

Umarım yardımcı olur,

Marc


+1: Sanırım çoğu insan kırmızıyla kastettiği şey bu. Bir hata durumunu göstermesini sağlamak.
kuantum

3

Genellikle ilerleme çubuğu ya temalıdır ya da kullanıcının renk tercihlerine uygundur. Dolayısıyla rengi değiştirmek için görsel stilleri kapatmanız veForeColor ve kontrolü kendiniz ya da çizmeniz gerekir.

Bloklar yerine sürekli stilde gelince, Styleözelliği ayarlayabilirsiniz :

pBar.Style = ProgressBarStyle.Continuous;

2

DÜZENLE

Yeşil blok tabanlı prog çubuğuna sahip XP Temasını kullandığınız şeylerin seslerine bakılırsa. Kullanıcı Arabirimi Stilinizi Windows Klasik'e çevirmeyi deneyin ve tekrar test edin, ancak tüm UI Stillerinde istediğinizi yapması için kendi OnPaint etkinliğinizi uygulamanız gerekebilir.

Veya başka birinin işaret ettiği gibi, uygulamanız için VisualStyles'ı devre dışı bırakın.

Orijinal

Bildiğim kadarıyla, İlerleme çubuğunun oluşturulması, seçtiğiniz Windows tema stiline (win2K, xp, vista) uygun olarak gerçekleşiyor.

Özelliği ayarlayarak rengi değiştirebilirsiniz.

ProgressBar.ForeColor

Ancak daha fazlasını yapabileceğinden emin değilim ...

biraz googling yapıyor

Burada MS KB'den "Sorunsuz" bir ilerleme çubuğu oluşturma üzerine bir makale var

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


@ Eion, Forecolor = kırmızı; Arka renk = mavi; Stil = Sürekli. Hiçbir şey değişmedi, hiç dokunmadım gibi kalıyor.
Ivan Prodanov


2

Tüm bu yöntemler benim için işe yaramıyor ancak bu yöntem onu ​​bir renk dizesine değiştirmenize izin veriyor.

Lütfen bu kodu StackOverflow'da başka bir yerden bulduğumu ve biraz değiştirdiğimi unutmayın. O zamandan beri bu kodu nerede bulduğumu unuttum ve bunun için çok üzgünüm.

Ama yine de umarım bu kod bana gerçekten yardımcı olan birine yardımcı olur.

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" adının kullanıldığı yerde, kendi ilerleme çubuğu adınızla değiştirin. Bu olayı diğer argümanlarla da tetikleyebilirsiniz, sadece iç parantezlerin bir yerde olduğundan emin olun.


iyi iş .. Işıktan karanlığa geçmek için bir ProgressChanged olayının içinde kullanıyorum ... + 1
BENN1TH

2

Değiştir ColorveValue (anında değişim)

Koymak using System.Runtime.InteropServices;En üste ...

İle ara ColorBar.SetState(progressBar1, ColorBar.Color.Yellow, myValue);

Çubuğun değerini değiştirirseniz (ne kadar büyükse), varsayılan yeşilden farklı bir renkte ise değişmeyeceğini fark ettim. User1032613'ün kodunu aldım ve bir Değer seçeneği ekledim.

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
Biz kapak vardı pBar.Value = pBar.Maximum;ve SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);doğru yeni renk göstermeye devam şartı vücut içine.
DomTheDeveloper

1

Herhangi birinin başka bir seçenek araması durumunda .... bir Paneli genişletebilir, arka plan olarak kullanabilir (beyaz veya her neyse), ön plan için içine başka bir Panel ekleyebilirsiniz (hareketli çubuk). Ardından rengi vb. Değiştirmek için tam kontrole sahip olursunuz.


1

Visual Basic Solution Explorer'da (vb dosyalarınızın olduğu yerde) projenize sağ tıklayın ve menüden özellikleri seçin. Açılan pencerede "XP Görsel Stillerini Etkinleştir" seçeneğinin işaretini kaldırın ve şimdi ön rengi ayarladığınızda, şimdi çalışmalıdır.


0

Јοеу: Alıntı: Genellikle ilerleme çubuğu ya temalıdır ya da kullanıcının renk tercihlerine uygundur. Dolayısıyla rengi değiştirmek için görsel stilleri kapatmanız veForeColor ve kontrolü kendiniz ya da çizmeniz gerekir.

Bloklar yerine sürekli stilde gelince, Styleözelliği ayarlayabilirsiniz :

pBar.Style = ProgressBarStyle.Continuous;

ProgressBarStyle.Continuous ile Blocksus, VistualStyles etkinken işe yaramaz ...

Blok (lar) yalnızca görsel stiller devre dışı bırakıldığında çalışacaktır ... bu da tüm bunları tartışmalı hale getirir (özel ilerleme rengiyle ilgili olarak) Görsel stiller devre dışı bırakıldığında ... ilerleme çubuğu ön renge göre renklendirilmelidir.

William Daniel'in cevabının bir kombinasyonunu kullandım (görsel stiller etkinleştirildiğinde, ForeColor sadece düz olmayacak, böylece ForeColor sadece düz olmayacak) ve Barry'nin cevabının (ilerleme çubuğundaki özel metne) şuradan: ProgressBar'a nasıl metin koyarım?


0

Aşağı için Yukarı Dikey Çubuk kırmızı renkte:

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

    } 
}

Lütfen bunun sorunu nasıl çözdüğünü metinle veya yorumlarla koda açıklar mısınız?
Harrison

Bunun bir nit olduğunun farkındayım (çünkü Minimum neredeyse her zaman sıfırdır); ancak Anal-kalıcı olarak doğru olması için Yükseklik ölçeği faktörünün (((double) Value - (double) Minimum) / ((double) Maximum - (double) Minimum)) olması gerekir. :)
Jesse Chisholm

0

WXP Görsel Stillerine saygı duyan VB.Net renkli ilerleme çubuğu cevabı ...

17/3/12 tarihinde 'user1032613'ün cevabıyla başladım. Bunun artık bir Modül olduğunu, bir sınıf olmadığını unutmayın. Oradan kodu dönüştürdüm ama daha fazlasına ihtiyaç vardı. Özellikle dönüştürülen kod, 'durum' tamsayısını çalışmayan bir IntPtr türüne dönüştürmek için bir DirectCast işlevi gösterdi.

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

Ve yine bunu kullanma kodunda şu satırla çağırın:

Call ModifyProgressBarColor.SetState(prb, 2)

BTW - Diğer renkleri denedim - 0, 4, 5 - hepsi sadece yeşil görüntülendi.


0

Şu anda yanıtlanamayacak kadar eski olduğunu biliyorum .. ama yine de @ Daniel için küçük bir değişiklik sıfır değerli ilerleme çubuğu göstermeme sorununu düzeltmek için yanıtına . İlerlemeyi yalnızca iç dikdörtgenin genişliği sıfır değilse çizin.

Tüm katkıda bulunanlara teşekkürler.

        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

Bunun ilerleme çubuğunun içine bir dikdörtgen çizerek ve genişliğini ilerlemenin mevcut değerine göre ayarlayarak yapılabileceğini buldum. Sağdan sola ilerleme desteği de ekledim. Bu şekilde Görüntüyü kullanmanız gerekmez ve Rectnalge.Inflate olarak adlandırılmadığından, çizilen dikdörtgen daha küçüktür.

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

Bence en basit çözümler, bu sadece hızlı bir düzeltme, ancak Program.cs'den Application.EnableVisualStyles () 'ı silebilir, yorumlayabilir veya Main işlevini içeren parçanızın adını verebilirsiniz. Bundan sonra progressBar.ForeColor = Color.TheColorYouDesire ile ilerleme çubuğundaki rengi serbestçe değiştirebilirsiniz;

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

-5

Düzenleme: iki minuitte, vs'yi ateşlemem ve çok daha iyi yanıtlarla ona yenildiğim sözdizimini kontrol etmem gerekti. bu siteyi seviyorum.

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

2
Çalışmıyor Şimdi boş kalıyor, progressBar1.value = 50 ekledim, ancak hala boş
Ivan Prodanov

maksimum değeri ayarlamayı denediniz mi? progressBar1 = yeni ProgressBar (); progressBar1.ForeColor = Color.Red; progressBar1.Maximum = 100;
Fusspawn

2
Hayır, sorun Windows temamda.
Ivan Prodanov

Bunun işe yarayıp yaramayacağı hakkında hiçbir fikriniz yok, ancak Application.EnableVisualThemes () 'i yorumlamayı deneyin; Bu, önceden oluşturulmuş dosyalardan biriyle oluşturulmuş dosyalar arasında (ne olduğunu hatırlayamıyorum)
Fusspawn

1
Application.EnableVisualStyles () üzgünüm temalar değil
Fusspawn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.