2016-12-03 25 views
6

Tôi có một điều khiển ProgressBar như hai sau:Invert Màu Chữ tùy thuộc vào BackColor

enter image description here

Việc đầu tiên là sơn đúng cách. Như bạn thấy, cái thứ hai chỉ có một số 0, nó có nghĩa là có hai nhưng cái kia không thể được nhìn thấy bởi vì ForeColor của ProgressBar giống như TextColor. Có cách nào tôi có thể vẽ văn bản màu đen khi ProgressBar bên dưới được tô màu Vôi và tô màu văn bản trong Vôi khi nền có màu đen?

+0

Thanh tiến trình nào? Nó được tích hợp sẵn hay bạn đang sử dụng một số tùy chỉnh hoặc kiểm soát của bên thứ ba? – vendettamit

+0

@vendettamit Xin lỗi, quên để chỉ định, tôi đang sử dụng https://www.codeproject.com/tips/645899/csharp-alternative-progressbar –

+1

Nếu văn bản là một phần không thể, trừ khi bạn sẽ sử dụng bitmap và chuyển đổi pixel. Nếu bạn có thể chia nó thành hai phần, bạn sẽ cần phải quyết định xem phần chia tách có cần chia các ký tự hay không. Không chính xác dễ dàng theo bất kỳ cách nào. Oh nhưng đối với các chế độ vẽ xor-ing cũ .. Giải pháp rẻ và dễ dàng nhất tôi thấy là thỏa hiệp về màu sắc và không chọn cùng độ sáng (độ sáng) cho thanh và văn bản .. – TaW

Trả lời

11

Trước tiên, bạn có thể vẽ nền và văn bản, sau đó vẽ hình chữ nhật vôi foreground bằng PatBlt phương pháp với PATINVERT tham số để kết hợp vẽ foreground với bản vẽ nền:

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

Lưu ý: Các điều khiển chỉ để minh họa logic sơn. Đối với ứng dụng thế giới thực, bạn cần phải thêm một số xác thực trên các thuộc tính Minimum, MaximumValue.

+2

Tốt nhất! Cảm thấy giống như những ngày cũ .. – TaW

+0

Đó chính xác là những gì tôi cần! Cảm ơn bạn! –

+0

Bạn được chào đón :) –

Các vấn đề liên quan