首页 > 其他分享 >WinForm(三)揭开可视化控件的面纱

WinForm(三)揭开可视化控件的面纱

时间:2022-12-10 11:14:57浏览次数:46  
标签:控件 Checked CheckBoxState width 可视化 using new WinForm

  WinForm所见即所得的UI设计框架,开发效率确实有所提升,同时降低了编程门槛,让WinForm更普及。拖拖拽拽就能设计出一个界面,那么我们拖拽的这些东西是什么?它们是什么原理?。

  WinForm我觉得很好的一点是,把所有东西都对像化(毕竟C#是面向对象的语言),包括可视化的窗体,控件等,当然有的控件在运行时是能看见的,比如按钮,文本框,下拉列表框等等,还有一类是在运时看不见的,比如Timers,FileSystemWatcher等。这些全都构建成了对象,那么看得见的控件是怎么看得见的呢?答案是绘制出来的,画出来才能看得见。是用GDI+技术画出来的。

  为了能够让大家更深入的理解,我们现在画一个Switch控件,Switch是苹果体系里的控件,在WinForm中,系统控件是没有的。Switch的作用非常像CheckBox,所以我们就参照CheckBoxRenderer来画,只不过画的形状不一样,具体代码如下:

using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms.VisualStyles;

namespace WinFormDemo02
{
    public class Switch : Control
    {
        private Rectangle textRectangleValue = new Rectangle();
        private CheckBoxState state = CheckBoxState.UncheckedNormal;
        public Switch(): base()
        {
            this.Location = new Point(50, 50);
            this.Size = new Size(50, 25);
            this.Font = SystemFonts.IconTitleFont;
            DoubleBuffered = true;
            SetStyle(ControlStyles.OptimizedDoubleBuffer |
                        ControlStyles.ResizeRedraw |
                        ControlStyles.AllPaintingInWmPaint, true);
        }
        public bool Checked
        {
            get; set;
        } = false;

        void DrawSwitch(Graphics g)
        {
            var x = 0;
            var y = 0;
            var width = 25;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            g.InterpolationMode = InterpolationMode.High;
            g.CompositingQuality = CompositingQuality.HighQuality;
            SolidBrush brush;
            if (Checked)
            {
                brush = new SolidBrush(Color.MediumSeaGreen);
            }
            else
            {
                brush = new SolidBrush(Color.DarkRed);
            }
            g.FillPie(brush, new Rectangle(x, y, width, width), 90, 180);
            g.FillRectangle(brush, new Rectangle(x + width / 2 - 1, y, width, width));
            g.FillPie(brush, new Rectangle(x + width - 2, y, width, width), -90, 180);
            if (Checked)
            {
                var selectBrush = new SolidBrush(Color.White);
                g.FillEllipse(selectBrush, new Rectangle(x + 2, y + 2, width - 4, width - 4));
            }
            else
            {
                var selectBrush = new SolidBrush(Color.White);
                g.FillEllipse(selectBrush, new Rectangle(x + width, y + 2, width - 4, width - 4));
            }
        }

        public Rectangle TextRectangle
        {
            get
            {
                using (Graphics g = this.CreateGraphics())
                {
                    textRectangleValue.X = ClientRectangle.X +
                        CheckBoxRenderer.GetGlyphSize(g,
                        CheckBoxState.UncheckedNormal).Width;
                    textRectangleValue.Y = ClientRectangle.Y;
                    textRectangleValue.Width = ClientRectangle.Width -
                        CheckBoxRenderer.GetGlyphSize(g,
                        CheckBoxState.UncheckedNormal).Width;
                    textRectangleValue.Height = ClientRectangle.Height;
                }
                return textRectangleValue;
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            DrawSwitch(e.Graphics);
            base.OnPaint(e);
        }
        public event EventHandler CheckedChanged;
        protected override void onm ouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (!Checked)
            {
                Checked = true;
                state = CheckBoxState.CheckedPressed;
                Invalidate();
            }
            else
            {
                Checked = false;
                state = CheckBoxState.UncheckedNormal;
                Invalidate();
            }
            CheckedChanged(this,new EventArgs());
        }
        protected override void onm ouseHover(EventArgs e)
        {
            base.OnMouseHover(e);
            state = Checked ? CheckBoxState.CheckedHot :
                CheckBoxState.UncheckedHot;
            Invalidate();
        }
        protected override void onm ouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            this.OnMouseHover(e);
        }
        protected override void onm ouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            state = Checked ? CheckBoxState.CheckedNormal :
                CheckBoxState.UncheckedNormal;
            Invalidate();
        }
    }
}

  我只是简单的实现了一下,重点在DrawSwitch这个方法,就是画两个半圆,中间是一个正方形,然后在上面画一个白圆,根据Checked属性,最上面的白圆在两边切换,仅此而以。

  通过上面例子,不知你是否了解了可视化控件的实现方式。如果你是初学者,完整的思路不太通,没关系,理解到控件是画出来的就够了,后面应该会说到GDI+的详细技术点。如果你是WinForm老手,可以自己实现一套自己的专用控件,把Window上的应用Run出Mac的感觉,甚至IOS的感觉。

  想要更快更方便的了解相关知识,可以关注微信公众号 

 

 

标签:控件,Checked,CheckBoxState,width,可视化,using,new,WinForm
From: https://www.cnblogs.com/ljknlb/p/16971056.html

相关文章

  • WinForm(一):开始一个WinForm程序
    WinForm程序只能运行在Windows上,即使是基于.NET5,6,7也一样。因为WinForm的UI层对接的底层API是基于Windows的。用VisualStudio创建一个WinForm应用很简单,建议使用非.......
  • WinForm(二):WinFrom中Main函数的入参和出参
    基本上有独立进程的应用,都是以Main函数作为入口,开始运行的。在C#中,Main函数可以无参无返回值,当然也可以是有string[]参数和int返返回值的。WinFrom也满足这个规则。......
  • WinForm(二):WinFrom中Main函数的入参和出参
    基本上有独立进程的应用,都是以Main函数作为入口,开始运行的。在C#中,Main函数可以无参无返回值,当然也可以是有string[]参数和int返返回值的。WinFrom也满足这个规则。......
  • WinForm(三)揭开可视化控件的面纱
    WinForm所见即所得的UI设计框架,开发效率确实有所提升,同时降低了编程门槛,让WinForm更普及。拖拖拽拽就能设计出一个界面,那么我们拖拽的这些东西是什么?它们是什么原理?。......
  • WinForm(二):WinFrom中Main函数的入参和出参
    基本上有独立进程的应用,都是以Main函数作为入口,开始运行的。在C#中,Main函数可以无参无返回值,当然也可以是有string[]参数和int返返回值的。WinFrom也满足这个规则。......
  • WinForm(一):开始一个WinForm程序
    WinForm程序只能运行在Windows上,即使是基于.NET5,6,7也一样。因为WinForm的UI层对接的底层API是基于Windows的。用VisualStudio创建一个WinForm应用很简单,建议使用非......
  • WinForm(一):开始一个WinForm程序
    WinForm程序只能运行在Windows上,即使是基于.NET5,6,7也一样。因为WinForm的UI层对接的底层API是基于Windows的。用VisualStudio创建一个WinForm应用很简单,建议使用非......
  • PyTorch中学习率调度器可视化介绍
    神经网络有许多影响模型性能的超参数。一个最基本的超参数是学习率(LR),它决定了在训练步骤之间模型权重的变化程度。在最简单的情况下,LR值是0到1之间的固定值。选择正确的......
  • MAUI新生5.2-样式外观:控件状态样式VisualState
    (当前版本V7.0.94,VisualState有bug)控件状态指控件当前处于什么使用状态,如禁用、聚焦、鼠标悬停等等,当控件进入到某种状态时,可以通过【附加属性】【VisualStateManager.Visu......
  • ASP.NET 2.0中使用webpart系列控件
    <v:shapetypeid="_x0000_t75"coordsize="21600,21600"o:spt="75"o:preferrelative="t"path="m@4@5l@4@11@9@11@9@5xe"filled="f"stroked="f">原文发表在​​http://......