创建显示进度的 Windows 窗体控件

创建显示进度的 Windows 窗体控件

下面的代码示例演示一个名为 FlashTrackBar 的自定义控件,该控件可用于向用户显示应用程序的级别或进度。它使用渐变以直观的方式表示进度。

FlashTrackBar 控件阐释了以下概念:

定义自定义属性。

定义自定义事件。((FlashTrackBar 定义 ValueChanged 事件。)

重写 OnPaint 方法以提供绘制控件的逻辑。

通过使用其 ClientRectangle 属性计算可用于绘制控件的区域。FlashTrackBar 在其 OptimizedInvalidate 方法中执行此计算。

当在 Windows 窗体设计器中更改属性时实现属性的序列化(持久性)。FlashTrackBar 定义 ShouldSerializeStartColor 和 ShouldSerializeEndColor 方法以序列化其 StartColor 和 EndColor 属性。

下表显示由 FlashTrackBar 定义的自定义属性。

属性  说明 
AllowUserEdit
 指示用户是否可以通过单击和拖动来更改闪烁跟踪条的值。
 
EndColor
 指定跟踪条的结束颜色。
 
DarkenBy
 指定根据前景渐变加深背景颜色的程度。
 
Max
 指定跟踪条的最大值。
 
Min
 指定跟踪条的最小值。
 
StartColor
 指定渐变的开始颜色。
 
ShowPercentage
 指示是否在渐变之上显示百分比。
 
ShowValue
 指示是否在渐变之上显示当前值。
 
ShowGradient
 指示跟踪条是否应显示表明当前值的颜色渐变。
 
Value
 指定跟踪条的当前值。

下表显示由 FlashTrackBar: 定义的附加成员:property-changed 事件以及引发该事件的方法。

成员  说明 
ValueChanged
 当跟踪条的 Value 属性改变时引发的事件。
 
OnValueChanged
 引发 ValueChanged 事件的方法。

注意
FlashTrackBar 将 EventArgs 类用于事件数据,将 EventHandler 用于事件委托。

为了处理相应的 EventName 事件,FlashTrackBar 重写它从 System.Windows.Forms.Control 继承的以下方法:

OnPaint

OnMouseDown

OnMouseMove

OnMouseUp

OnResize

为了处理相应的 property-changed 事件,FlashTrackBar 重写它从 System.Windows.Forms.Control 继承的以下方法:

OnBackColorChanged

OnBackgroundImageChanged

OnTextChanged

示例
FlashTrackBar 控件定义两种用户界面类型编辑器:FlashTrackBarValueEditor 和 FlashTrackBarDarkenByEditor,如下面的代码清单所示。HostApp 类在 Windows 窗体上使用 FlashTrackBar 控件。


namespace Microsoft.Samples.WinForms.Cs.FlashTrackBar {
    using System;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Design;
    using System.Windows.Forms;
    using System.Diagnostics;

    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    public class FlashTrackBar : System.Windows.Forms.Control {
        /// <summary>
        ///    Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components;

        private const int LeftRightBorder = 10;
        private int value = 0;
        private int min = 0;
        private int max = 100;
        private bool showPercentage = false;
        private bool showValue = false;
        private bool allowUserEdit = true;
        private bool showGradient = true;
        private int dragValue = 0;
        private bool dragging = false;
        private Color startColor = Color.Red;
        private Color endColor = Color.LimeGreen;
        private EventHandler onValueChanged;
        private Brush baseBackground = null;
        private Brush backgroundDim = null;
        private byte darkenBy = 200;


        public FlashTrackBar() {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

            SetStyle(ControlStyles.Opaque, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            Debug.Assert(GetStyle(ControlStyles.ResizeRedraw), "Should be redraw!");
        }

        /// <summary>
        ///    Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
           if (disposing) {
                if (components != null) {
                    components.Dispose();
                }
           }
           base.Dispose(disposing);
        }

        /// <summary>
        ///    Required method for Designer support - do not modify
        ///    the contents of this method with the code editor.
        /// </summary>
        void InitializeComponent () {
            this.components = new System.ComponentModel.Container ();
            this.ForeColor = System.Drawing.Color.White;
            this.BackColor = System.Drawing.Color.Black;
            this.Size = new System.Drawing.Size(100, 23);
            this.Text = "FlashTrackBar";
        }

        [
            Category("Flash"),
            DefaultValue(true)
        ]
        public bool AllowUserEdit {
            get {
                return allowUserEdit;
            }
            set {
                if (value != allowUserEdit) {
                    allowUserEdit = value;
                    if (!allowUserEdit) {
                        Capture = false;
                        dragging = false;
                    }
                }
            }
        }

        [
            Category("Flash")
        ]
        public Color EndColor {
            get {
                return endColor;
            }
            set {
                endColor = value;
                if (baseBackground != null && showGradient) {
                    baseBackground.Dispose();
                    baseBackground = null;
                }
                Invalidate();
            }
        }

        public bool ShouldSerializeEndColor() {
            return !(endColor == Color.LimeGreen);
        }


        [
            Category("Flash"),
            Editor(typeof(FlashTrackBarDarkenByEditor), typeof(UITypeEditor)),
            DefaultValue((byte)200)
        ]
        public byte DarkenBy {
            get {
                return darkenBy;
            }
            set {
                if (value != darkenBy) {
                    darkenBy = value;
                    if (backgroundDim != null) {
                        backgroundDim.Dispose();
                        backgroundDim = null;
                    }
                    OptimizedInvalidate(Value, max);
                }
            }
        }

        [
            Category("Flash"),
            DefaultValue(100)
        ]
        public int Max {
            get {
                return max;
            }
            set {
                if (max != value) {
                    max = value;
                    Invalidate();
                }
            }
        }

        [
            Category("Flash"),
            DefaultValue(0)
        ]
        public int Min {
            get {
                return min;
            }
            set {
                if (min != value) {
                    min = value;
                    Invalidate();
                }
            }
        }

        [
            Category("Flash")
        ]
        public Color StartColor {
            get {
                return startColor;
            }
            set {
                startColor = value;
                if (baseBackground != null && showGradient) {
                    baseBackground.Dispose();
                    baseBackground = null;
                }
                Invalidate();
            }
        }

        public bool ShouldSerializeStartColor() {
            return !(startColor == Color.Red);
        }

 

        [
            Category("Flash"),
            RefreshProperties(RefreshProperties.Repaint),
            DefaultValue(false)
        ]
        public bool ShowPercentage {
            get {
                return showPercentage;
            }
            set {
                if (value != showPercentage) {
                    showPercentage = value;
                    if (showPercentage) {
                        showValue = false;
                    }
                    Invalidate();
                }
            }
        }

        [
            Category("Flash"),
            RefreshProperties(RefreshProperties.Repaint),
            DefaultValue(false)
        ]
        public bool ShowValue {
            get {
                return showValue;
            }
            set {
                if (value != showValue) {
                    showValue = value;
                    if (showValue) {
                        showPercentage = false;
                    }
                    Invalidate();
                }
            }
        }

        [
            Category("Flash"),
            DefaultValue(true)
        ]
        public bool ShowGradient {
            get {
                return showGradient;
            }
            set {
                if (value != showGradient) {
                    showGradient = value;
                    if (baseBackground != null) {
                        baseBackground.Dispose();
                        baseBackground = null;
                    }
                    Invalidate();
                }
            }
        }

        [
            Category("Flash"),
            Editor(typeof(FlashTrackBarValueEditor), typeof(UITypeEditor)),
            DefaultValue(0)
        ]
        public int Value {
            get {
                if (dragging) {
                    return dragValue;
                }
                return value;
            }
            set {
                if (value != this.value) {
                    int old = this.value;
                    this.value = value;
                    OnValueChanged(EventArgs.Empty);
                    OptimizedInvalidate(old, this.value);
                }
            }
        }

        // ValueChanged Event
        [Description("Raised when the Value displayed changes")]
        public event EventHandler ValueChanged {
            add {
                onValueChanged += value;
            }
            remove {
                onValueChanged -= value;
            }
        }

        private void OptimizedInvalidate(int oldValue, int newValue) {
            Rectangle client = ClientRectangle;

            float oldPercentValue = ((float)oldValue / ((float)Max - (float)Min));
            int oldNonDimLength = (int)(oldPercentValue * (float)client.Width);

            float newPercentValue = ((float)newValue / ((float)Max - (float)Min));
            int newNonDimLength = (int)(newPercentValue * (float)client.Width);

            int min = Math.Min(oldNonDimLength, newNonDimLength);
            int max = Math.Max(oldNonDimLength, newNonDimLength);

            Rectangle invalid = new Rectangle(
                client.X + min,
                client.Y,
                max - min,
                client.Height);

            Invalidate(invalid);

            string oldToDisplay;
            string newToDisplay;

            if (ShowPercentage) {
                oldToDisplay = Convert.ToString((int)(oldPercentValue * 100f)) + "%";
                newToDisplay = Convert.ToString((int)(newPercentValue * 100f)) + "%";
            }
            else if (ShowValue) {
                oldToDisplay = Convert.ToString(oldValue);
                newToDisplay = Convert.ToString(newValue);
            }
            else {
                oldToDisplay = null;
                newToDisplay = null;
            }

            if (oldToDisplay != null && newToDisplay != null) {
                Graphics g = CreateGraphics();
                SizeF oldFontSize = g.MeasureString(oldToDisplay, Font);
                SizeF newFontSize = g.MeasureString(newToDisplay, Font);
                RectangleF oldFontRect = new RectangleF(new PointF(0, 0), oldFontSize);
                RectangleF newFontRect = new RectangleF(new PointF(0, 0), newFontSize);
                oldFontRect.X = (client.Width - oldFontRect.Width) / 2;
                oldFontRect.Y = (client.Height - oldFontRect.Height) / 2;
                newFontRect.X = (client.Width - newFontRect.Width) / 2;
                newFontRect.Y = (client.Height - newFontRect.Height) / 2;

                Invalidate(new Rectangle((int)oldFontRect.X, (int)oldFontRect.Y, (int)oldFontRect.Width, (int)oldFontRect.Height));
                Invalidate(new Rectangle((int)newFontRect.X, (int)newFontRect.Y, (int)newFontRect.Width, (int)newFontRect.Height));
            }
        }

        protected override void OnMouseDown(MouseEventArgs e) {
            base.OnMouseDown(e);
            if (!allowUserEdit) {
                return;
            }
            Capture = true;
            dragging = true;
            SetDragValue(new Point(e.X, e.Y));
        }

        protected override void OnMouseMove(MouseEventArgs e) {
            base.OnMouseMove(e);
            if (!allowUserEdit || !dragging) {
                return;
            }
            SetDragValue(new Point(e.X, e.Y));
        }

        protected override void OnMouseUp(MouseEventArgs e) {
            base.OnMouseUp(e);
            if (!allowUserEdit || !dragging) {
                return;
            }
            Capture = false;
            dragging = false;
            value = dragValue;
            OnValueChanged(EventArgs.Empty);
        }

        protected override void OnPaint(PaintEventArgs e) {

            base.OnPaint(e);
            if (baseBackground == null) {
                if (showGradient) {
                    baseBackground = new LinearGradientBrush(new Point(0, 0),
                                                             new Point(ClientSize.Width, 0),
                                                             StartColor,
                                                             EndColor);
                }
                else if (BackgroundImage != null) {
                    baseBackground = new TextureBrush(BackgroundImage);
                }
                else {
                    baseBackground = new SolidBrush(BackColor);
                }
            }

            if (backgroundDim == null) {
                backgroundDim = new SolidBrush(Color.FromArgb(DarkenBy, Color.Black));
            }

            Rectangle toDim = ClientRectangle;
            float percentValue = ((float)Value / ((float)Max - (float)Min));
            int nonDimLength = (int)(percentValue * (float)toDim.Width);
            toDim.X += nonDimLength;
            toDim.Width -= nonDimLength;


            string text = Text;
            string toDisplay = null;
            RectangleF textRect = new RectangleF();

            if (ShowPercentage || ShowValue || text.Length > 0) {

                if (ShowPercentage) {
                    toDisplay = Convert.ToString((int)(percentValue * 100f)) + "%";
                }
                else if (ShowValue) {
                    toDisplay = Convert.ToString(Value);
                }
                else {
                    toDisplay = text;
                }

                SizeF textSize = e.Graphics.MeasureString(toDisplay, Font);
                textRect.Width = textSize.Width;
                textRect.Height = textSize.Height;
                textRect.X = (ClientRectangle.Width - textRect.Width) / 2;
                textRect.Y = (ClientRectangle.Height - textRect.Height) / 2;
            }

            e.Graphics.FillRectangle(baseBackground, ClientRectangle);
            e.Graphics.FillRectangle(backgroundDim, toDim);
            e.Graphics.Flush();
            if (toDisplay != null && toDisplay.Length > 0) {
                e.Graphics.DrawString(toDisplay, Font, new SolidBrush(ForeColor), textRect);
            }
        }

        protected override void OnTextChanged(EventArgs e) {
            base.OnTextChanged(e);
            Invalidate();
        }

        protected override void OnBackColorChanged(EventArgs e) {
            base.OnTextChanged(e);
            if ((baseBackground != null) && (!showGradient)) {
                        baseBackground.Dispose();
                        baseBackground = null;
            }
        }

        protected override void OnBackgroundImageChanged(EventArgs e) {
            base.OnTextChanged(e);
            if ((baseBackground != null) && (!showGradient)) {
                        baseBackground.Dispose();
                        baseBackground = null;
            }
        }

        protected override void OnResize(EventArgs e) {
            base.OnResize(e);
            if (baseBackground != null) {
                baseBackground.Dispose();
                baseBackground = null;
            }
        }

        protected virtual void OnValueChanged(EventArgs e) {
            if (onValueChanged != null) {
                onValueChanged.Invoke(this, e);
            }
        }

        private void SetDragValue(Point mouseLocation) {

            Rectangle client = ClientRectangle;

            if (client.Contains(mouseLocation)) {
                float percentage = (float)mouseLocation.X / (float)ClientRectangle.Width;
                int newDragValue = (int)(percentage * (float)(max - min));
                if (newDragValue != dragValue) {
                    int old = dragValue;
                    dragValue = newDragValue;
                    OptimizedInvalidate(old, dragValue);
                }
            }
            else {
                if (client.Y <= mouseLocation.Y && mouseLocation.Y <= client.Y + client.Height) {
                    if (mouseLocation.X <= client.X && mouseLocation.X > client.X - LeftRightBorder) {
                        int newDragValue = min;
                        if (newDragValue != dragValue) {
                            int old = dragValue;
                            dragValue = newDragValue;
                            OptimizedInvalidate(old, dragValue);
                        }
                    }
                    else if (mouseLocation.X >= client.X + client.Width && mouseLocation.X < client.X + client.Width + LeftRightBorder) {
                        int newDragValue = max;
                        if (newDragValue != dragValue) {
                            int old = dragValue;
                            dragValue = newDragValue;
                            OptimizedInvalidate(old, dragValue);
                        }
                    }
                }
                else {
                    if (dragValue != value) {
                        int old = dragValue;
                        dragValue = value;
                        OptimizedInvalidate(old, dragValue);
                    }
                }
            }
        }
    }
}


namespace Microsoft.Samples.WinForms.Cs.FlashTrackBar {
   using System;
   using System.ComponentModel;
   using System.ComponentModel.Design;
   using System.Diagnostics;
   using System.Drawing;
   using System.Drawing.Drawing2D;
   using System.Drawing.Design;
   using System.Windows.Forms;
   using System.Windows.Forms.ComponentModel;
   using System.Windows.Forms.Design;

   public class FlashTrackBarDarkenByEditor : FlashTrackBarValueEditor {
       protected override void SetEditorProps(FlashTrackBar editingInstance, FlashTrackBar editor) {
           base.SetEditorProps(editingInstance, editor);
           editor.Min = 0;
           editor.Max = byte.MaxValue;
       }
   }
}


namespace Microsoft.Samples.WinForms.Cs.FlashTrackBar {
    using System;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Diagnostics;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Design;
    using System.Windows.Forms;
    using System.Windows.Forms.ComponentModel;
    using System.Windows.Forms.Design;

    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    public class FlashTrackBarValueEditor : System.Drawing.Design.UITypeEditor {

        private IWindowsFormsEditorService edSvc = null;

        protected virtual void SetEditorProps(FlashTrackBar editingInstance, FlashTrackBar editor) {
            editor.ShowValue = true;
            editor.StartColor = Color.Navy;
            editor.EndColor = Color.White;
            editor.ForeColor = Color.White;
            editor.Min = editingInstance.Min;
            editor.Max = editingInstance.Max;
        }

        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) {

            if (context != null
                && context.Instance != null
                && provider != null) {

                edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));

                if (edSvc != null) {
                    FlashTrackBar trackBar = new FlashTrackBar();
                    trackBar.ValueChanged += new EventHandler(this.ValueChanged);
                    SetEditorProps((FlashTrackBar)context.Instance, trackBar);
                    bool asInt = true;
                    if (value is int) {
                        trackBar.Value = (int)value;
                    }
                    else if (value is byte) {
                        asInt = false;
                        trackBar.Value = (byte)value;
                    }
                    edSvc.DropDownControl(trackBar);
                    if (asInt) {
                        value = trackBar.Value;
                    }
                    else {
                        value = (byte)trackBar.Value;
                    }
                }
            }

            return value;
        }

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) {
            if (context != null && context.Instance != null) {
                return UITypeEditorEditStyle.DropDown;
            }
            return base.GetEditStyle(context);
        }

        private void ValueChanged(object sender, EventArgs e) {
            if (edSvc != null) {
                edSvc.CloseDropDown();
            }
        }
    }
}


namespace Microsoft.Samples.WinForms.Cs.HostApp {
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows.Forms;
    using Microsoft.Samples.WinForms.Cs.FlashTrackBar;

    public class HostApp : System.Windows.Forms.Form {
        /// <summary>
        ///    Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components;
        protected internal Microsoft.Samples.WinForms.Cs.FlashTrackBar.FlashTrackBar flashTrackBar1;

        public HostApp() {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

        }

        /// <summary>
        ///    Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
           if (disposing) {
                if (components != null) {
                    components.Dispose();
                }
           }
           base.Dispose(disposing);
        }

        /// <summary>
        ///    Required method for Designer support - do not modify
        ///    the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent() {
            this.components = new System.ComponentModel.Container ();
            this.flashTrackBar1 = new Microsoft.Samples.WinForms.Cs.FlashTrackBar.FlashTrackBar ();
            this.Text = "Control Example";
            this.ClientSize = new System.Drawing.Size (600, 450);
            flashTrackBar1.BackColor = System.Drawing.Color.Black;
            flashTrackBar1.Dock = System.Windows.Forms.DockStyle.Fill;
            flashTrackBar1.TabIndex = 0;
            flashTrackBar1.ForeColor = System.Drawing.Color.White;
            flashTrackBar1.Text = "Drag the Mouse and say Wow!";
            flashTrackBar1.Value = 73;
            flashTrackBar1.Size = new System.Drawing.Size (600, 450);
            this.Controls.Add (this.flashTrackBar1);
        }

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        public static void Main(string[] args) {
            Application.Run(new HostApp());
        }

    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值