2016-12-03 13 views
6

Mam ProgressBar kontrolę jak następujących dwóch kryteriów:Odwróć Kolor tekstu w zależności od Backcolor

enter image description here

Pierwszym jest prawidłowo malowane. Jak widać, druga ma tylko jedno 0, powinna mieć dwa, ale druga nie może być widoczna, ponieważ ProgressBar's ForeColor jest taki sam jak TextColor. Czy istnieje sposób, w jaki mogę pomalować tekst na czarno, kiedy ProgressBar poniżej jest namalowany w Wapieniu i malować tekst w Wapni, gdy tło jest czarne?

+0

Który pasek postępu to jest? Czy jest on wbudowany, czy używasz kontroli niestandardowej lub zewnętrznej? – vendettamit

+0

@vendettamit Przepraszamy, zapomniałem podać, używam https://www.codeproject.com/tips/645899/csharp-alternative-progressbar –

+1

Jeśli tekst jest jednoczęściowy, nie jest to możliwe, chyba że użyjesz bitmapy i przełącz piksele. Jeśli możesz podzielić to na dwie części, musisz zdecydować, czy podział musi dzielić znaki. W żaden sposób nie jest to łatwe. Och, ale dla starych trybów rysowania. Jedyne tanie i łatwe rozwiązanie, jakie widzę, to pójść na kompromis w sprawie kolorów i nie wybrać tego samego (jasność) dla paska i tekstu .. – TaW

Odpowiedz

11

można najpierw narysować tło i tekst, a następnie narysować pierwszoplanowy wapno prostokąta przy użyciu PatBlt metodę z PATINVERT parametru połączyć pierwszoplanowy rysunek z tła rysunku:

enter image description here

enter image description here

using System; 
using System.Drawing; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 
public class MyProgressBar : Control 
{ 
    public MyProgressBar() 
    { 
     DoubleBuffered = true; 
     Minimum = 0; Maximum = 100; Value = 50; 
    } 
    public int Minimum { get; set; } 
    public int Maximum { get; set; } 
    public int Value { get; set; } 
    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 
     Draw(e.Graphics); 
    } 
    private void Draw(Graphics g) 
    { 
     var r = this.ClientRectangle; 
     using (var b = new SolidBrush(this.BackColor)) 
      g.FillRectangle(b, r); 
     TextRenderer.DrawText(g, this.Value.ToString(), this.Font, r, this.ForeColor); 
     var hdc = g.GetHdc(); 
     var c = this.ForeColor; 
     var hbrush = CreateSolidBrush(((c.R | (c.G << 8)) | (c.B << 16))); 
     var phbrush = SelectObject(hdc, hbrush); 
     PatBlt(hdc, r.Left, r.Y, (Value * r.Width/Maximum), r.Height, PATINVERT); 
     SelectObject(hdc, phbrush); 
     DeleteObject(hbrush); 
     g.ReleaseHdc(hdc); 
    } 
    public const int PATINVERT = 0x005A0049; 
    [DllImport("gdi32.dll")] 
    public static extern bool PatBlt(IntPtr hdc, int nXLeft, int nYLeft, 
     int nWidth, int nHeight, int dwRop); 
    [DllImport("gdi32.dll")] 
    public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); 
    [DllImport("gdi32.dll", EntryPoint = "DeleteObject")] 
    public static extern bool DeleteObject(IntPtr hObject); 
    [DllImport("gdi32.dll")] 
    public static extern IntPtr CreateSolidBrush(int crColor); 
} 

Uwaga: Sterowanie służy tylko do demonstracji logiki malowania. W przypadku aplikacji działającej w świecie rzeczywistym konieczne jest dodanie poprawności dla właściwości Minimum, Maximum i Value.

+2

Niezły! Czujesz się jak za dawnych czasów. – TaW

+0

Dokładnie tego potrzebuję! Dziękuję Ci! –

+0

Nie ma za co :) –