Wie ändere ich die Farbe des Fortschrittsbalkens in C # .NET 3.5?

91

Ich möchte zwei Dinge in meinem Fortschrittsbalken tun.

  1. Ändern Sie die grüne Farbe in rot.
  2. Entfernen Sie die Blöcke und machen Sie es in einer Farbe.

Alle Informationen über diese beiden Dinge, die ich frage, wie man sie erreicht, werden sehr geschätzt!

Vielen Dank.

Ivan Prodanov
quelle

Antworten:

82

Da die vorherigen Antworten nicht mit visuellen Stilen zu funktionieren scheinen. Sie müssen wahrscheinlich Ihre eigene Klasse erstellen oder den Fortschrittsbalken erweitern:

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

BEARBEITEN: Der Code wurde aktualisiert, damit der Fortschrittsbalken den visuellen Stil für den Hintergrund verwendet

Chris Persichetti
quelle
2
Vielen Dank dafür, damit konnte ich in meiner Lösung arbeiten.
Irwin
Das ist wirklich cool, danke. Es hat mir wirklich geholfen, an etwas zu arbeiten, an dem ich gerade arbeite, obwohl ich es geändert habe, um jedes Mal das gesamte Steuerelement neu zu streichen, anstatt nur den von e.ClipRectangle angegebenen Bereich. Andernfalls wurde es nicht korrekt neu gezeichnet, nachdem nur ein Teil des Steuerelements durch ein anderes Fenster oder den Bildschirmrand ungültig gemacht wurde.
Matt Blaine
@ Matt Blaine: Könnten Sie bitte Ihre Änderung als Bearbeitung zur Antwort posten? Ich glaube, es wird genug Leute geben, die sich für Ihre Komplettlösung interessieren.
Marek
@Marek Habe gerade deinen Kommentar bemerkt. Ich habe nicht genug Mitarbeiter, um die Antwort zu bearbeiten, also habe ich meine eigenen gepostet. Vielen Dank. stackoverflow.com/questions/778678/…
Matt Blaine
3
Mir ist klar, dass das alt ist; und mir ist klar, dass dies eine Nichte ist (weil das Minimum fast immer Null ist); Der Breitenskalierungsfaktor sollte jedoch (((doppelt) Wert - (doppelt) Minimum) / ((doppelt) Maximum - (doppelt) Minimum) sein , um anal-remanent korrekt zu sein. :)
Jesse Chisholm
122

OK, ich habe eine Weile gebraucht, um alle Antworten und Links zu lesen. Folgendes habe ich aus ihnen herausgeholt:

Probenergebnisse

Die akzeptierte Antwort deaktiviert visuelle Stile. Sie können die Farbe auf alles einstellen, was Sie möchten, aber das Ergebnis sieht einfach aus:

Geben Sie hier die Bildbeschreibung ein

Mit der folgenden Methode können Sie stattdessen so etwas erhalten:

Geben Sie hier die Bildbeschreibung ein

Wie man

Fügen Sie dies zunächst hinzu, wenn Sie nicht: using System.Runtime.InteropServices;

Zweitens können Sie entweder diese neue Klasse erstellen oder ihren Code in eine vorhandene staticnicht generische Klasse einfügen :

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

Um es zu verwenden, rufen Sie einfach an:

progressBar1.SetState(2);

Beachten Sie den zweiten Parameter in SetState, 1 = normal (grün); 2 = Fehler (rot); 3 = Warnung (gelb).

Ich hoffe es hilft!

user1032613
quelle
18
Sie haben eine Erweiterungsmethode erstellt, daher sollte der Aufruf progressBar1.SetState (2) lauten. außerdem tolle Antwort!
Edgar Hernandez
5
Zu beachten ist, dass dies nur unter Vista + verfügbar ist. Sie können die vollständige Dokumentation anzeigen, indem Sie nach PBM_SETSTATE suchen .
Djof
Wunderschönen! Vielen Dank
Sapbucket
1
Das ist erstaunlich, aber es bricht meine Fortschrittsanzeige teilweise, es wird sich nie zu 100% füllen ...
Norbert Boros
1
public const uint PBM_SETSTATE = 0x0410; // 1040
Andrei Krasutski
37

Dies ist eine flimmerfreie Version des am meisten akzeptierten Codes, den Sie als Antwort auf diese Frage finden können. Alle Ehre gebührt den Plakaten dieser fetten Antworten. Danke Dusty, Chris, Matt und Josh!

Wie die Anfrage von "Fueled" in einem der Kommentare brauchte ich auch eine Version, die sich etwas professioneller verhält. Dieser Code behält Stile wie im vorherigen Code bei, fügt jedoch eine Offscreen-Bildwiedergabe und Grafikpufferung hinzu (und entsorgt das Grafikobjekt ordnungsgemäß).

Ergebnis: alles Gute und kein Flackern. :) :)

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
quelle
Nun, dies kommt der ursprünglichen Implementierung von Microsoft am nächsten.
Yakup Ünyılmaz
1
Ein using-Block zu haben und Dispose aufzurufen, ist eigentlich etwas redundant. Tolle Antwort.
Kevin Stricker
1
Mir ist klar, dass das alt ist; und mir ist klar, dass dies eine Nichte ist (weil das Minimum fast immer Null ist); Der Breitenskalierungsfaktor sollte jedoch (((doppelt) Wert - (doppelt) Minimum) / ((doppelt) Maximum - (doppelt) Minimum) sein , um anal-remanent korrekt zu sein. :)
Jesse Chisholm
Wenn ich TextRenderer.DrawText () verwende, um Text in ein Offscreen-Bild zu zeichnen, sieht das Endergebnis auf dem Bildschirm pixelig aus und ähnelt keiner Beschriftung mit genau derselben Schriftart. Wenn Sie dies alles direkt auf e.Graphics ohne den Offscreenimager zeichnen, erhalten Sie das richtige Ergebnis ... Irgendwelche Ideen warum?
CuriousGeorge
1
Ja, ich habe versucht, unskaliert zu blitten. Schließlich habe ich gerade zu WPF gewechselt, also ist alles, was ich brauche, eingebaut.
CuriousGeorge
28

Im Designer müssen Sie nur die ForeColor-Eigenschaft auf die gewünschte Farbe festlegen. Im Fall von Rot gibt es eine vordefinierte Farbe dafür.

Um dies im Code (C #) zu tun, gehen Sie wie folgt vor:

pgs.ForeColor = Color.Red;

Bearbeiten : Oh ja, setzen Sie auch den Stil auf kontinuierlich. Im Code wie folgt:

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

Noch eine Änderung: Sie müssen auch die Zeile entfernen, die Application.EnableVisualStyles()von Ihrem Program.cs(oder ähnlichem) liest . Wenn Sie dies nicht tun können, weil der Rest der Anwendung visuelle Stile haben soll, würde ich empfehlen, das Steuerelement selbst zu malen oder zu WPF überzugehen, da dies mit WPF einfach ist. Sie finden ein Tutorial zum Eigentümer, der einen Fortschrittsbalken in Codeplex zeichnet

Dustyburwell
quelle
3
Vorfarbe = rot; Hintergrundfarbe = blau; Stil = Kontinuierlich. Nichts hat sich geändert, es bleibt so, als hätte ich es nie berührt
Ivan Prodanov
3
bah ... okay, ich sehe das Problem. Sie müssen visuelle Stile deaktivieren, damit dies mit den Eigenschaften funktioniert. Es wird wahrscheinlich mit einem beliebigen Thema gemalt. In Program.cs gibt es eine Zeile mit der Aufschrift Application.EnableVisualStyles (). Entfernen Sie diese Linie und dies wird funktionieren. Andernfalls müssen Sie das Steuerelement selbst malen. Die andere Option ist die Verwendung von WPF (wenn dies möglich ist), da Sie diese Art von Dingen sehr einfach erledigen können.
Dustyburwell
Bitte geben Sie mir weitere Informationen zu "Wie ich es selbst male".
Ivan Prodanov
1
Hier ist ein Tutorial zum Zeichnen eines Fortschrittsbalkens durch den Besitzer. Der Prozess ist viel zu kompliziert für einen Kommentar. codeproject.com/KB/cpp/VistaProgressBar.aspx
Dustyburwell
1
Es ist eine Schande, Application.EnableVisualStyles () ist der Schlüsselteil dieser Lösung. Leider bricht dies alle anderen Stile.
mr.user1065741
15

Mit den Antworten von Matt Blaine und Chris Persichetti habe ich einen Fortschrittsbalken erstellt, der ein bisschen schöner aussieht und gleichzeitig eine unendliche Farbauswahl ermöglicht (im Grunde habe ich eine Zeile in Matts Lösung geändert):

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

Verwendung:

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

Ergebnisse

Sie können einen beliebigen Farbverlauf verwenden!

Herunterladen

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

Josh M.
quelle
2
Mir ist klar, dass das alt ist; und mir ist klar, dass dies eine Nichte ist (weil das Minimum fast immer Null ist); Der Breitenskalierungsfaktor sollte jedoch (((doppelt) Wert - (doppelt) Minimum) / ((doppelt) Maximum - (doppelt) Minimum) sein , um anal-remanent korrekt zu sein. :)
Jesse Chisholm
Die Antwort mit Ihrem Vorschlag wurde aktualisiert.
Josh M.
Ich weiß, dass es alt ist, aber - dieser Code wird fehlerhaft, sobald er einen Wert von 4 erreicht, da LinearGradientBrushdie Aufzeichnungsbreite als 0 gelesen wird. Die einfachste Lösung besteht darin, das "Auffüllen" von 4px im Code nicht durchzuführen und ihn stattdessen einzufügen ein Panel oder etwas mit Polsterung (wenn Sie einen Rand wollen) und machen rec.Width = (int)((rec.Width * scaleFactor) - 4)inrec.Width = (int)(rec.Width * scaleFactor) + 1
MiDri
14

Änderung der Antwort von Dustyburwell. (Ich habe nicht genug Mitarbeiter, um es selbst zu bearbeiten.) Wie seine Antwort funktioniert es mit aktivierten "Visual Styles". Sie können einfach die ForeColor-Eigenschaft des Fortschrittsbalkens in der Entwurfsansicht eines beliebigen Formulars festlegen.

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
quelle
Dies eignet sich hervorragend zum Ändern der Vordergrundfarbe, flackert jedoch stark, während das Standard-ProgressBar-Steuerelement dies nicht tut. Irgendeine Idee, wie man das löst?
Betankt
4
Ich habe herausgefunden, wie das Flackern behoben werden kann: Fügen Sie den ControlStyles der benutzerdefinierten ProgressBar eine doppelte Pufferung hinzu: SetStyle (ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, ...).
Betankt
Mir ist klar, dass das alt ist; und mir ist klar, dass dies eine Nichte ist (weil das Minimum fast immer Null ist); Der Breitenskalierungsfaktor sollte jedoch (((doppelt) Wert - (doppelt) Minimum) / ((doppelt) Maximum - (doppelt) Minimum) sein , um anal-remanent korrekt zu sein. :)
Jesse Chisholm
5

Ich habe das einfach in eine statische Klasse eingeordnet.

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

Ich hoffe es hilft,

Marc

Marc
quelle
+1: Ich denke, das haben die meisten Leute mit Rot gemeint. Es wird ein Fehlerstatus angezeigt.
Quantum
3

Normalerweise ist der Fortschrittsbalken entweder thematisch oder berücksichtigt die Farbeinstellungen des Benutzers. Um die Farbe zu ändern, müssen Sie entweder die visuellen Stile deaktivieren und festlegenForeColor das Steuerelement selbst oder zeichnen.

Für den fortlaufenden Stil anstelle von Blöcken können Sie die StyleEigenschaft festlegen :

pBar.Style = ProgressBarStyle.Continuous;
Joey
quelle
2

BEARBEITEN

Nach den Geräuschen der Dinge verwenden Sie das XP-Theme mit der auf grünen Blöcken basierenden Prog-Bar. Versuchen Sie, Ihren UI-Stil auf Windows Classic umzustellen und erneut zu testen. Möglicherweise müssen Sie jedoch Ihr eigenes OnPaint-Ereignis implementieren, damit es für alle UI-Stile das tut, was Sie möchten

Oder deaktivieren Sie, wie bereits erwähnt, die VisualStyles für Ihre Anwendung.

Original

Soweit ich weiß, erfolgt das Rendern des Fortschrittsbalkens in Übereinstimmung mit dem von Ihnen gewählten Windows-Designstil (win2K, xp, vista).

Sie können die Farbe ändern, indem Sie die Eigenschaft festlegen

ProgressBar.ForeColor

Ich bin mir nicht sicher, ob Sie noch viel mehr können ...

googelt ein bisschen

Hier ist ein Artikel von MS KB über das Erstellen eines "glatten" Fortschrittsbalkens

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

Eoin Campbell
quelle
@ Eion, Forecolor = rot; Hintergrundfarbe = blau; Stil = Kontinuierlich. Nichts hat sich geändert, es bleibt so, als hätte ich es nie berührt.
Ivan Prodanov
2

Alle diese Methoden funktionieren bei mir nicht, aber mit dieser Methode können Sie sie in eine Farbzeichenfolge ändern.

Bitte beachten Sie, dass ich diesen Code von irgendwo anders auf StackOverflow gefunden und ein wenig geändert habe. Ich habe seitdem vergessen, wo ich diesen Code gefunden habe und kann ihn deshalb nicht verlinken. Tut mir leid.

Aber trotzdem hoffe ich, dass dieser Code jemandem hilft, der mir wirklich geholfen hat.

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

Wenn der Name "ProgressBar" verwendet wird, ersetzen Sie ihn durch Ihren eigenen Fortschrittsbalkennamen. Sie können dieses Ereignis auch mit anderen Argumenten auslösen. Stellen Sie nur sicher, dass sich die Klammern irgendwo befinden.

EpicNinjaCheese
quelle
Gute Arbeit ... Ich benutze in einem ProgressChanged-Event, um von hell nach dunkel zu
wechseln
2

Änderung Colorund Value(sofortige Änderung)

Setzen Sie using System.Runtime.InteropServices;oben ...

Rufen Sie an mit ColorBar.SetState(progressBar1, ColorBar.Color.Yellow, myValue);

Ich habe festgestellt, dass sich der Wert des Balkens (wie groß er ist) nicht ändert, wenn er eine andere Farbe als das Standardgrün hat. Ich habe den Code von user1032613 genommen und eine Wertoption hinzugefügt.

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
quelle
2
Wir mussten umdrehen pBar.Value = pBar.Maximum;und uns SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);innerhalb des Zustandskörpers befinden, damit der Fortschritt die richtige neue Farbe zeigte.
DomTheDeveloper
1

Nur für den Fall, dass jemand nach einer anderen Option sucht ... Sie können ein Bedienfeld erweitern, es als Hintergrund verwenden (weiß oder was auch immer) und ein weiteres Bedienfeld für den Vordergrund (die bewegliche Leiste) hinzufügen. Dann haben Sie die volle Kontrolle über das Ändern der Farbe usw.

Eduardo
quelle
1

Klicken Sie einfach mit der rechten Maustaste auf Ihr Projekt in Visual Basic Solution Explorer (wo sich Ihre vb-Dateien befinden) und wählen Sie Eigenschaften aus dem Menü aus. Deaktivieren Sie im daraufhin angezeigten Fenster die Option "XP-Stile aktivieren". Wenn Sie jetzt die Vorfarbe festlegen, sollte dies jetzt funktionieren.

Geil
quelle
0

:Οеу: Quote: Normalerweise ist der Fortschrittsbalken entweder thematisch oder berücksichtigt die Farbeinstellungen des Benutzers. Um die Farbe zu ändern, müssen Sie entweder die visuellen Stile deaktivieren und festlegenForeColor das Steuerelement selbst oder zeichnen.

Für den fortlaufenden Stil anstelle von Blöcken können Sie die StyleEigenschaft festlegen :

pBar.Style = ProgressBarStyle.Continuous;

ProgressBarStyle.Continuous versus Blocks ist bei aktivierten VistualStyles unbrauchbar ...

Block (s) funktionieren nur mit deaktivierten visuellen Stilen ... was all dies zu einem strittigen Punkt macht (in Bezug auf die benutzerdefinierte Fortschrittsfarbe). Wenn deaktivierte visuelle Stile ... sollte der Fortschrittsbalken basierend auf der Vorfarbe gefärbt sein.

Ich habe eine Kombination aus William Daniels Antwort (mit aktivierten visuellen Stilen, damit die ForeColor nicht nur flach und ohne Stil ist) und Barrys Antwort (auf benutzerdefinierten Text in der Fortschrittsleiste) verwendet: Wie füge ich Text in ProgressBar ein?

NeoH4x0r
quelle
0

Vertikale Leiste UP For Down in roter Farbe:

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
quelle
Können Sie bitte entweder im Text oder in Kommentaren zum Code erklären, wie dies das Problem löst?
Harrison
Mir ist klar, dass dies eine Nichte ist (weil Minimum fast immer Null ist); Der Höhenskalierungsfaktor sollte jedoch (((doppelt) Wert - (doppelt) Minimum) / ((doppelt) Maximum - (doppelt) Minimum) sein , um anal-remanent korrekt zu sein. :)
Jesse Chisholm
0

Die farbige Fortschrittsleiste von VB.Net, die die Antwort von WXP Visual Styles berücksichtigt, lautet ...

Ich habe mit der Antwort von 'user1032613' am 17.03.12 begonnen. Beachten Sie, dass dies jetzt ein Modul ist, keine Klasse. Von dort habe ich den Code konvertiert, aber es wurde mehr benötigt. Insbesondere zeigte der konvertierte Code eine DirectCast-Funktion zum Konvertieren der Ganzzahl 'state' in einen IntPtr-Typ, der nicht funktionierte.

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

Und wieder rufen Sie dies einfach im using-Code mit dieser Zeile auf:

Call ModifyProgressBarColor.SetState(prb, 2)

Übrigens - ich habe andere Farben ausprobiert - 0, 4, 5 - sie haben alle nur grün angezeigt.

DanW52
quelle
0

Ich weiß, dass es viel zu alt ist, um jetzt beantwortet zu werden. Aber dennoch eine kleine Änderung an @ Daniels Antwort, um das Problem zu beheben, dass kein nullwertiger Fortschrittsbalken angezeigt wird. Zeichnen Sie den Fortschritt nur, wenn festgestellt wird, dass die Breite des inneren Rechtecks ​​ungleich Null ist.

Vielen Dank an alle Mitwirkenden.

        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
quelle
0

Ich fand, dass dies durch Zeichnen eines Rechtecks ​​innerhalb des Fortschrittsbalkens und Festlegen der Breite entsprechend dem aktuellen Wert des Fortschritts erreicht werden kann. Ich habe auch Unterstützung für den Fortschritt von rechts nach links hinzugefügt. Auf diese Weise müssen Sie das Bild nicht verwenden, und da Rectnalge.Inflate nicht genannt wird, ist das gezeichnete Rechteck kleiner.

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
quelle
0

Ich denke, dass die einfachste Lösung von allen nur eine schnelle Lösung ist, aber Sie können die Application.EnableVisualStyles () aus Program.cs löschen, kommentieren oder wie auch immer Sie den Teil benennen, der die Hauptfunktion enthält. Danach können Sie die Farbe des Fortschrittsbalkens mit progressBar.ForeColor = Color.TheColorYouDesire frei ändern.

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

Bearbeiten: In den beiden Minuten brauchte ich, um vs zu starten und die Syntax zu überprüfen, mit der ich geschlagen wurde, mit viel besseren Antworten. Ich liebe diese Seite.

        progressBar1 = new ProgressBar();
        progressBar1.ForeColor = Color.Red;
Fusspawn
quelle
2
Funktioniert nicht. Es bleibt jetzt leer, ich habe progressBar1.value = 50 hinzugefügt, aber immer noch leer
Ivan Prodanov
versucht, den Maximalwert einzustellen? progressBar1 = new ProgressBar (); progressBar1.ForeColor = Color.Red; progressBar1.Maximum = 100;
Fusspawn
2
Nein, das Problem liegt in meinem Windows-Thema.
Ivan Prodanov
Keine Ahnung, ob dies funktionieren wird, aber versuchen Sie, Application.EnableVisualThemes () auskommentieren; das ist in einer der vorgefertigten Dateien vs generieren (ich kann mich nicht erinnern, welche)
Fusspawn
1
Application.EnableVisualStyles () sorry nicht Themen
Fusspawn