从WinForms应用程序控制WPF进度栏 [英] Control WPF progress bar from WinForms app

查看:72
本文介绍了从WinForms应用程序控制WPF进度栏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用vb .net构建的WinForms应用程序,并向其中添加了WPF用户控件.WPF用户控件仅包含一个进度条.我可以将WPF控件从toolbax拖动到WinForms vb .net中的Main Form中.但是我不知道如何让我的WinForms应用程序动态设置WPF进度栏的值.无论如何,我可以从WinForms应用程序动态设置WPF控件进度栏的值吗?

注意:我使用WPF进度条而不使用WinForms进度条的原因是为了使我可以在WinForms应用程序中使用蓝色的进度条.

解决方案

由于它可能不像在纸上看起来那样简单,因此这里有一个自定义的ProgressBar,它可以设置条形的颜色并更改其样式即时.

ProgressBarStyle 属性设置当前样式: BarStyle.Standard 样式使用

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

 导入System.ComponentModel导入System.Drawing.Drawing2D导入System.Drawing导入System.Windows.Forms< DesignerCategory(代码")>公共类ProgressBarCustomColor继承ProgressBar私有m_ParentBackColor为Color = SystemColors.Window私有m_ProgressBarStyle为BarStyle = BarStyle.Standard私人m_FlatBorderColor为Color = Color.White公开子New()SetStyle(ControlStyles.AllPaintingInWmPaint或ControlStyles.UserPaint或ControlStyles.OptimizedDoubleBuffer,True)结束子公共枚举BarStyle标准平坦的结束枚举公共属性ProgressBarStyle作为BarStyle得到返回m_ProgressBarStyle结束获取放m_ProgressBarStyle =值如果是DesignMode,则Me.Parent?.Refresh()端套最终财产公共属性FlatBorderColor作为颜色得到返回m_FlatBorderColor结束获取放m_FlatBorderColor =值如果是DesignMode,则Me.Parent?.Refresh()端套最终财产受保护的重写Sub OnParentChanged(例如EventArgs)MyBase.OnParentChanged(e)m_ParentBackColor = If(Me.Parent不算什么,Me.Parent.BackColor,SystemColors.Window)结束子受保护的重写Sub OnPaintBackground(例如,作为PaintEventArgs)MyBase.OnPaintBackground(e)暗淡= Me.ClientRectangle如果m_ProgressBarStyle = BarStyle.Standard,则ProgressBarRenderer.DrawHorizo​​ntalBar(e.Graphics,rect)Dim baseColor = Color.FromArgb(240,Me.BackColor)昏暗的highColor = Color.FromArgb(160,baseColor)使用baseBrush = New SolidBrush(baseColor),highBrush =新的SolidBrush(highColor)e.Graphics.FillRectangle(highBrush,1,2,rect.Width,9)e.Graphics.FillRectangle(baseBrush,1,7,rect.Width,rect.Height-1)最终使用别的使用pen =新Pen(m_FlatBorderColor,2),baseBrush =新的SolidBrush(m_ParentBackColor)e.Graphics.FillRectangle(baseBrush,0,0,矩​​形宽度-1,矩形高度-1)e.Graphics.DrawRectangle(pen,1,1,Me.ClientSize.Width-2,Me.ClientSize.Height-2)最终使用万一结束子受保护的重写Sub OnPaint(e作为PaintEventArgs)Dim rect =新RectangleF(PointF.Empty,Me.ClientSize)rect.Width = CType(rect.Width *(CType(Me.Value,Single)/Me.Maximum),Integer)rect.Size =新的SizeF(rect.Width-2,rect.Height)Dim hsl as Single = Me.ForeColor.GetBrightness()如果m_ProgressBarStyle = BarStyle.Standard,则DrawStandardBar(e.Graphics,rect,hsl)如果m_ProgressBarStyle = BarStyle.Flat,则DrawFlatBar(e.Graphics,rect,hsl)结束子私有子DrawStandardBar(g作为图形,rect作为RectangleF,hsl作为单个)g.SmoothingMode = SmoothingMode.AntiAliasg.CompositingQuality = CompositingQuality.HighQualityDim baseColor = Color.FromArgb(240,Me.ForeColor)昏暗的highColor = Color.FromArgb(160,baseColor)使用baseBrush = New SolidBrush(baseColor),highBrush =新的SolidBrush(highColor),sf = New StringFormat(StringFormatFlags.MeasureTrailingSpaces)sf.LineAlignment = StringAlignment.Centersf.Alignment = StringAlignment.Centerg.FillRectangle(highBrush,1,2,rect.Width,9)g.FillRectangle(baseBrush,1,7,rect.Width,rect.Height-1)g.DrawString($"{Me.Value}%",Me.Parent.Font,如果(hsl> 0.49F,Brushes.Black,Brushes.White),Me.ClientRectangle,sf)最终使用结束子私有子DrawFlatBar(g作为图形,rect作为RectangleF,hsl作为单个)使用baseBrush = New SolidBrush(SystemColors.Highlight)g.FillRectangle(baseBrush,2,2,rect.Width-2,rect.Height-4)最终使用结束子末级 

C#版本:

 使用System.ComponentModel;使用System.Drawing;使用System.Drawing.Drawing2D;使用System.Windows.Forms;[DesignerCategory(代码")]公共类ProgressBarCustomColor:ProgressBar{私人颜色m_ParentBackColor = SystemColors.Window;私人颜色m_FlatBorderColor = Color.White;私人BarStyle m_ProgressBarStyle = BarStyle.Standard;公共ProgressBarCustomColor(){this.SetStyle(ControlStyles.AllPaintingInWmPaint |ControlStyles.UserPaint |ControlStyles.OptimizedDoubleBuffer,true);}公共枚举BarStyle {Standard,Flat}公共BarStyle ProgressBarStyle {得到=>m_ProgressBarStyle;放 {m_ProgressBarStyle =值;如果(DesignMode)this.Parent?.Refresh();}}公共颜色FlatBorderColor {得到=>m_FlatBorderColor;放 {m_FlatBorderColor =值;如果(DesignMode)this.Parent?.Refresh();}}受保护的重写void OnParentChanged(EventArgs e){base.OnParentChanged(e);m_ParentBackColor = this.Parent?.BackColor?SystemColors.Window;}受保护的重写void OnPaintBackground(PaintEventArgs e){base.OnPaintBackground(e);var rect = this.ClientRectangle;如果(m_ProgressBarStyle == BarStyle.Standard){ProgressBarRenderer.DrawHorizo​​ntalBar(e.Graphics,rect);var baseColor = Color.FromArgb(240,this.BackColor);var highColor = Color.FromArgb(160,baseColor);使用(var baseBrush = new SolidBrush(baseColor))使用(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);}}别的 {使用(var pen = new Pen(m_FlatBorderColor,2))使用(var baseBrush = new SolidBrush(m_ParentBackColor)){e.Graphics.FillRectangle(baseBrush,0,0,矩​​形宽度-1,矩形高度-1);e.Graphics.DrawRectangle(pen,1,1,this.ClientSize.Width-2,this.ClientSize.Height-2);}}}受保护的重写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();如果(m_ProgressBarStyle == BarStyle.Standard)DrawStandardBar(e.Graphics,rect,hsl);如果(m_ProgressBarStyle == BarStyle.Flat)DrawFlatBar(e.Graphics,rect,hsl);}私有无效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);使用(var baseBrush = new SolidBrush(baseColor))使用(var highBrush = new SolidBrush(highColor))使用(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);}}私有void DrawFlatBar(图形g,RectangleF rect,float hsl){使用(var baseBrush = new SolidBrush(SystemColors.Highlight)){g.FillRectangle(baseBrush,2,2,rect.Width-2,rect.Height-4);}}} 

I have an WinForms app built with vb .net to which I've added a WPF user control. The WPF user control consists of only a progressbar. I can drag the WPF control from the toolbax and add it to the Main Form in WinForms vb .net. But I don't know how to let my WinForms app dynamically set the value for the WPF progress bar. Anyway I can dynamically set the WPF control progress bar's value from my WinForms app?

Note: The reason Im using WPF progress bar instead of using WinForms progress bar is so that I can have blue colored progress bar in my WinForms app.

解决方案

Since it may not be as straightforward as it may look like on paper, here's a custom ProgressBar that allows to set the Color of the bar and also change its style on the fly.

The ProgressBarStyle property sets the current style: the BarStyle.Standard style uses the ProgressBarRenderer.DrawHorizontalBar() method to draw its background, while the BarStyle.Flat selects the Parent.BackColor as background color and uses a fixed white border to draw the ProgressBar bounds and SystemColors.Highlight as the bar color. Of course it can be changed to support any other color and the Standard style.

The StringFormat class is used to center the text of the ProgressBar (in Standard style only. This can also be easily changed), setting both Horizontal and Vertical alignment to StringAlignment.Center.
The text color changes automatically to adapt to the Brightness of the ProgressBar color (it's just a simple adjustment, the HSL value on its own cannot always determine what text color better fits a background color).

Some magic values are just offsets used to adapt the drawing rectangles to the shapes designed by ProgressBarRenderer


This is how it works:

VB.Net version of the Custom Control:

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# version:

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

这篇关于从WinForms应用程序控制WPF进度栏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆