簡體   English   中英

從 WinForms 應用程序控制 WPF 進度條

[英]Control WPF progress bar from WinForms app

我有一個用 vb .net 構建的 WinForms 應用程序,我在其中添加了一個 WPF 用戶控件。 WPF 用戶控件僅包含一個進度條。 我可以從工具箱中拖動 WPF 控件並將其添加到 WinForms vb .net 的主窗體中。 但我不知道如何讓我的 WinForms 應用程序動態設置 WPF 進度條的值。 無論如何,我可以從我的 WinForms 應用程序動態設置 WPF 控制進度條的值嗎?

注意:我使用 WPF 進度條而不是使用 WinForms 進度條的原因是我可以在我的 WinForms 應用程序中使用藍色進度條。

由於它可能不像紙上看起來那么簡單,這里有一個自定義的 ProgressBar,它允許設置欄的顏色並動態更改其樣式

ProgressBarStyle屬性設置當前樣式: BarStyle.Standard樣式使用ProgressBarRenderer.DrawHorizontalBar()方法繪制其背景,而BarStyle.Flat選擇Parent.BackColor作為背景顏色並使用固定的白色邊框繪制 ProgressBar 邊界和SystemColors.Highlight作為條形顏色。 當然,它可以更改為支持任何其他顏色和標准樣式。

StringFormat class 用於將 ProgressBar 的文本居中(僅限Standard樣式。這也可以輕松更改),將水平和垂直 alignment 設置為StringAlignment.Center
文本顏色會自動更改以適應 ProgressBar 顏色的亮度(這只是一個簡單的調整, HSL值本身並不能始終確定哪種文本顏色更適合背景顏色)。

一些魔法值只是用於使繪圖矩形適應ProgressBarRenderer設計的形狀的偏移量


這是它的工作原理

進度條自定義

VB.Net 版本的自定義控件:

Imports System.ComponentModel
Imports System.Drawing.Drawing2D
Imports System.Drawing
Imports System.Windows.Forms

<DesignerCategory("Code")>
Public Class ProgressBarCustomColor
    Inherits ProgressBar

    Private m_ParentBackColor As Color = SystemColors.Window
    Private m_ProgressBarStyle As BarStyle = BarStyle.Standard
    Private m_FlatBorderColor As Color = Color.White

    Public Sub New()
        SetStyle(ControlStyles.AllPaintingInWmPaint Or
                 ControlStyles.UserPaint Or
                 ControlStyles.OptimizedDoubleBuffer, True)
    End Sub

    Public Enum BarStyle
        Standard
        Flat
    End Enum

    Public Property ProgressBarStyle As BarStyle
        Get
            Return m_ProgressBarStyle
        End Get
        Set
            m_ProgressBarStyle = Value
            If DesignMode Then Me.Parent?.Refresh()
        End Set
    End Property

    Public Property FlatBorderColor As Color
        Get
            Return m_FlatBorderColor
        End Get
        Set
            m_FlatBorderColor = Value
            If DesignMode Then Me.Parent?.Refresh()
        End Set
    End Property

    Protected Overrides Sub OnParentChanged(e As EventArgs)
        MyBase.OnParentChanged(e)
        m_ParentBackColor = If(Me.Parent IsNot Nothing, Me.Parent.BackColor, SystemColors.Window)
    End Sub

    Protected Overrides Sub OnPaintBackground(e As PaintEventArgs)
        MyBase.OnPaintBackground(e)
        Dim rect = Me.ClientRectangle

        If m_ProgressBarStyle = BarStyle.Standard Then
            ProgressBarRenderer.DrawHorizontalBar(e.Graphics, rect)

            Dim baseColor = Color.FromArgb(240, Me.BackColor)
            Dim highColor = Color.FromArgb(160, baseColor)
            Using baseBrush = New SolidBrush(baseColor),
                  highBrush = New SolidBrush(highColor)
                e.Graphics.FillRectangle(highBrush, 1, 2, rect.Width, 9)
                e.Graphics.FillRectangle(baseBrush, 1, 7, rect.Width, rect.Height - 1)
            End Using
        Else
            Using pen = New Pen(m_FlatBorderColor, 2),
                  baseBrush = New SolidBrush(m_ParentBackColor)
                e.Graphics.FillRectangle(baseBrush, 0, 0, rect.Width - 1, rect.Height - 1)
                e.Graphics.DrawRectangle(pen, 1, 1, Me.ClientSize.Width - 2, Me.ClientSize.Height - 2)
            End Using
        End If
    End Sub

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        Dim rect = New RectangleF(PointF.Empty, Me.ClientSize)
        rect.Width = CType(rect.Width * (CType(Me.Value, Single) / Me.Maximum), Integer)
        rect.Size = New SizeF(rect.Width - 2, rect.Height)

        Dim hsl As Single = Me.ForeColor.GetBrightness()
        If m_ProgressBarStyle = BarStyle.Standard Then DrawStandardBar(e.Graphics, rect, hsl)
        If m_ProgressBarStyle = BarStyle.Flat Then DrawFlatBar(e.Graphics, rect, hsl)
    End Sub

    Private Sub DrawStandardBar(g As Graphics, rect As RectangleF, hsl As Single)
        g.SmoothingMode = SmoothingMode.AntiAlias
        g.CompositingQuality = CompositingQuality.HighQuality

        Dim baseColor = Color.FromArgb(240, Me.ForeColor)
        Dim highColor = Color.FromArgb(160, baseColor)

        Using baseBrush = New SolidBrush(baseColor),
              highBrush = New SolidBrush(highColor),
              sf = New StringFormat(StringFormatFlags.MeasureTrailingSpaces)
            sf.LineAlignment = StringAlignment.Center
            sf.Alignment = StringAlignment.Center

            g.FillRectangle(highBrush, 1, 2, rect.Width, 9)
            g.FillRectangle(baseBrush, 1, 7, rect.Width, rect.Height - 1)
            g.DrawString($"{Me.Value} %", Me.Parent.Font,
                If(hsl > 0.49F, Brushes.Black, Brushes.White), Me.ClientRectangle, sf)
        End Using
    End Sub

    Private Sub DrawFlatBar(g As Graphics, rect As RectangleF, hsl As Single)
        Using baseBrush = New SolidBrush(SystemColors.Highlight)
            g.FillRectangle(baseBrush, 2, 2, rect.Width - 2, rect.Height - 4)
        End Using
    End Sub
End Class

C#版本:

using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

[DesignerCategory("Code")]
public class ProgressBarCustomColor : ProgressBar
{
    private Color m_ParentBackColor = SystemColors.Window;
    private Color m_FlatBorderColor = Color.White;
    private BarStyle m_ProgressBarStyle = BarStyle.Standard;
    public ProgressBarCustomColor()
    {
        this.SetStyle(
            ControlStyles.AllPaintingInWmPaint | 
            ControlStyles.UserPaint | 
            ControlStyles.OptimizedDoubleBuffer, true);
    }

    public enum BarStyle { Standard, Flat }

    public BarStyle ProgressBarStyle {
        get => m_ProgressBarStyle;
        set {
            m_ProgressBarStyle = value;
            if (DesignMode) this.Parent?.Refresh();
        }
    }

    public Color FlatBorderColor {
        get => m_FlatBorderColor;
        set {
            m_FlatBorderColor = value;
            if (DesignMode) this.Parent?.Refresh();
        }
    }

    protected override void OnParentChanged(EventArgs e)
    {
        base.OnParentChanged(e);
        m_ParentBackColor = this.Parent?.BackColor ?? SystemColors.Window;
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        base.OnPaintBackground(e);
        var rect = this.ClientRectangle;

        if (m_ProgressBarStyle == BarStyle.Standard) {
            ProgressBarRenderer.DrawHorizontalBar(e.Graphics, rect);

            var baseColor = Color.FromArgb(240, this.BackColor);
            var highColor = Color.FromArgb(160, baseColor);
            using (var baseBrush = new SolidBrush(baseColor))
            using (var highBrush = new SolidBrush(highColor)) {
                e.Graphics.FillRectangle(highBrush, 1, 2, rect.Width, 9);
                e.Graphics.FillRectangle(baseBrush, 1, 7, rect.Width, rect.Height - 1);
            }
        }
        else {
            using (var pen = new Pen(m_FlatBorderColor, 2))
            using (var baseBrush = new SolidBrush(m_ParentBackColor)) {
                e.Graphics.FillRectangle(baseBrush, 0, 0, rect.Width - 1, rect.Height - 1);
                e.Graphics.DrawRectangle(pen, 1, 1, this.ClientSize.Width - 2, this.ClientSize.Height - 2);
            }
        }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        var rect = new RectangleF(PointF.Empty, this.ClientSize);
        rect.Width = (int)(rect.Width * ((float)this.Value / this.Maximum));
        rect.Size = new SizeF(rect.Width - 2, rect.Height);

        float hsl = this.ForeColor.GetBrightness();
        if (m_ProgressBarStyle == BarStyle.Standard) DrawStandardBar(e.Graphics, rect, hsl);
        if (m_ProgressBarStyle == BarStyle.Flat) DrawFlatBar(e.Graphics, rect, hsl);
    }

    private void DrawStandardBar(Graphics g, RectangleF rect, float hsl)
    {
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.CompositingQuality = CompositingQuality.HighQuality;

        var baseColor = Color.FromArgb(240, this.ForeColor);
        var highColor = Color.FromArgb(160, baseColor);

        using (var baseBrush = new SolidBrush(baseColor))
        using (var highBrush = new SolidBrush(highColor))
        using (var sf = new StringFormat(StringFormatFlags.MeasureTrailingSpaces)) {
            sf.LineAlignment = StringAlignment.Center;
            sf.Alignment = StringAlignment.Center;

            g.FillRectangle(highBrush, 1, 2, rect.Width, 9);
            g.FillRectangle(baseBrush, 1, 7, rect.Width, rect.Height - 1);
            g.DrawString($"{this.Value} %", this.Parent.Font, 
                hsl > .49f ? Brushes.Black : Brushes.White, this.ClientRectangle, sf);
        }
    }

    private void DrawFlatBar(Graphics g, RectangleF rect, float hsl)
    {
        using (var baseBrush = new SolidBrush(SystemColors.Highlight)) {
            g.FillRectangle(baseBrush, 2, 2, rect.Width - 2, rect.Height - 4);
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM