十字星

  • 首页
  • 技术
  • 随笔
  • 瞎折腾
  • 平面设计
  • 文集
  • 留言
  • 其他
    • API测试
  1. 首页
  2. 技术
  3. 正文

自定义日历控件环境VS2019+NET4.6.1

2020-12-27 1230点热度 2人点赞 0条评论

原生控件领导觉得不好看要求重写,因此有了这篇文章,先上关键代码,以后有时间了在具体说明

自定义日历选择的弹出控件,对应文件.cs/.Designer.cs/.resx

xwMonthCalendar.cs

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

namespace xwDateTimePicker.DateTimePicker
{
    [ToolboxItem(false)]
    public partial class xwMonthCalendar : UserControl
    {
        #region 声明 
        readonly string[] Weekday = new string[] { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
        readonly DateTime[] TempDateDay = new DateTime[42];
        readonly xwDateTimePicker xwDateTimePicker;
        DateTime CurrentDate;
        #endregion
        readonly Font _font = new Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
        public xwMonthCalendar(xwDateTimePicker AlPicker)
        {
            InitializeComponent();
            this.BackColor = Color.White;
            xwDateTimePicker = AlPicker;
            this.CurrentDate = xwDateTimePicker.Value;
            _font = xwDateTimePicker.Font;
            DateInit();//初始设置
            ShowDate(CurrentDate.Year, CurrentDate.Month);
            labSelectedDate.Text = Weekday[(int)DateTime.Today.DayOfWeek] + " , " + DateTime.Today.Year + "/" + DateTime.Today.Month + "/" + DateTime.Today.Day;
        }
        private void DateInit()
        {
            #region 星期
            //周标题数组
            Label[] WeekScheme = new Label[7];
            string[] week = new string[] { "日", "一", "二", "三", "四", "五", "六" };
            for (int i = 0; i <= 6; i++)
            {
                WeekScheme[i] = new Label()
                {
                    Text = week[i],
                    Width = 20,
                    Height = 16,
                    Font = _font,
                    Location = new Point(3 + i * 25, 25),
                    ForeColor = Color.FromArgb(85, 85, 85)
                };
            }
            WeekScheme[0].ForeColor = WeekScheme[6].ForeColor = Color.FromArgb(255, 128, 128);
            #endregion
            this.Controls.AddRange(WeekScheme);
            int DateNum = 0;
            Label[] DateDay = new Label[42];
            for (int i = 0; i < 6; i++)
            {
                int y = 47 + i * 18;
                for (int j = 0; j < 7; j++)
                {
                    DateDay[DateNum] = new Label
                    {
                        Name = "AutoLabDateDay" + DateNum.ToString(),
                        Width = 23,
                        Height = 14,
                        Font = _font,
                        Location = new Point(1 + j * 25, y),
                        TextAlign = ContentAlignment.MiddleRight
                    };
                    DateNum++;
                }
            }
            this.Controls.AddRange(DateDay);
        }

        private void ShowDate(int year, int month)
        {
            labCurrentDate.Text = year + "年" + month + "月";
            //                             1   2   3   4   5   6   7   8   9   10  11  12
            int[] DataDayLen = new int[] { 31, 30, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
            DataDayLen[1] = ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0)) ? 29 : 28;
            DateTime MyDate = DateTime.Parse(year + "-" + month + "-" + 1);
            DateTime Today = DateTime.Today;
            int Day = (int)MyDate.DayOfWeek;

            for (int L = 0; L < 42; L++)
            {
                Label labDateDay = (Label)this.Controls["AutoLabDateDay" + L];
                labDateDay.Text = "";
                labDateDay.BackColor = Color.Transparent;
                //前一个月
                if (Day != 0 && L < Day)
                {
                    labDateDay.Text = (DataDayLen[MyDate.AddMonths(-1).Month - 1] - Day + L + 1).ToString();
                    labDateDay.ForeColor = Color.DarkGray;
                    TempDateDay[L] = DateTime.Parse(MyDate.AddMonths(-1).Year + "-" + MyDate.AddMonths(-1).Month + "-" + (DataDayLen[MyDate.AddMonths(-1).Month - 1] - Day + L + 1).ToString());

                    labDateDay.Tag = TempDateDay[L];
                }
                //当前月
                else if (L >= Day && L < DataDayLen[MyDate.Month - 1] + Day)
                {
                    labDateDay.Text = (L - Day + 1).ToString();
                    labDateDay.ForeColor = Color.FromArgb(85, 85, 85);
                    int day = Convert.ToInt32(labDateDay.Text);
                    labDateDay.Tag = DateTime.Parse(MyDate.Year + "-" + MyDate.Month + "-" + labDateDay.Text);
                }
                //下一个月
                else if (L >= DataDayLen[MyDate.Month - 1] + Day)
                {
                    labDateDay.Text = (L - DataDayLen[MyDate.Month - 1] - Day + 1).ToString();
                    TempDateDay[L] = DateTime.Parse(MyDate.AddMonths(+1).Year + "-" + MyDate.AddMonths(+1).Month + "-" + (L - DataDayLen[MyDate.Month - 1] - Day + 1).ToString());
                    labDateDay.ForeColor = Color.DarkGray;
                    labDateDay.Tag = TempDateDay[L];
                }

                labDateDay.MouseLeave += (sender, e) =>
                {
                    Label CuLabel = (Label)sender;
                    CuLabel.BackColor = Color.Transparent;
                };
                labDateDay.MouseClick += (sender, e) =>
                {
                    Label label = (Label)sender;
                    if (xwDateTimePicker != null)
                    {
                        DateTime time = Convert.ToDateTime(label.Tag);
                        xwDateTimePicker.Year = time.Year;
                        xwDateTimePicker.Month = time.Month;
                        xwDateTimePicker.Day = time.Day;
                        xwDateTimePicker.DropDownClose();
                    }
                };
                labDateDay.MouseEnter += (sender, e) =>
                {
                    Label label = (Label)sender;
                    label.BackColor = Color.FromArgb(247, 248, 249);
                    if (label.Tag != null)
                    {
                        DateTime time = Convert.ToDateTime(label.Tag);
                        labSelectedDate.Text = Weekday[(int)time.DayOfWeek] + " , " + time.Year + "-" + time.Month + "-" + time.Day;
                    }
                    else
                    {
                        labSelectedDate.Text = Weekday[(int)DateTime.Today.DayOfWeek] + " , " + DateTime.Today.Year + "-" + DateTime.Today.Month + "-" + DateTime.Today.Day;
                    }
                };
            }
        }

        private void LabPrevYear_Click(object sender, EventArgs e)
        {
            if (sender == labPrevYear) { CurrentDate = CurrentDate.AddYears(-1); }
            else if (sender == labPrevMonth) { CurrentDate = CurrentDate.AddMonths(-1); }
            else if (sender == labNextMonth) { CurrentDate = CurrentDate.AddMonths(+1); }
            else if (sender == labNextYear) { CurrentDate = CurrentDate.AddYears(+1); }

            ShowDate(CurrentDate.Year, CurrentDate.Month);
        }

        private void LabPrevYear_MouseEnter(object sender, EventArgs e)
        {
            ((Label)sender).BackColor = Color.FromArgb(247, 248, 249);
        }

        private void LabPrevYear_MouseLeave(object sender, EventArgs e)
        {
            ((Label)sender).BackColor = Color.Transparent;
        }
    }
}

xwMonthCalendar.Designer.cs

namespace xwDateTimePicker.DateTimePicker
{
    partial class xwMonthCalendar
    {
        /// <summary> 
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary> 
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region 组件设计器生成的代码

        /// <summary> 
        /// 设计器支持所需的方法 - 不要修改
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(xwMonthCalendar));
            this.labPrevYear = new System.Windows.Forms.Label();
            this.labPrevMonth = new System.Windows.Forms.Label();
            this.labNextMonth = new System.Windows.Forms.Label();
            this.labNextYear = new System.Windows.Forms.Label();
            this.labCurrentDate = new System.Windows.Forms.Label();
            this.labSelectedDate = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // labPrevYear
            // 
            this.labPrevYear.Image = ((System.Drawing.Image)(resources.GetObject("labPrevYear.Image")));
            this.labPrevYear.Location = new System.Drawing.Point(5, 5);
            this.labPrevYear.Name = "labPrevYear";
            this.labPrevYear.Size = new System.Drawing.Size(13, 13);
            this.labPrevYear.TabIndex = 0;
            this.labPrevYear.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            this.labPrevYear.Click += new System.EventHandler(this.LabPrevYear_Click);
            this.labPrevYear.MouseEnter += new System.EventHandler(this.LabPrevYear_MouseEnter);
            this.labPrevYear.MouseLeave += new System.EventHandler(this.LabPrevYear_MouseLeave);
            // 
            // labPrevMonth
            // 
            this.labPrevMonth.Image = ((System.Drawing.Image)(resources.GetObject("labPrevMonth.Image")));
            this.labPrevMonth.Location = new System.Drawing.Point(23, 5);
            this.labPrevMonth.Name = "labPrevMonth";
            this.labPrevMonth.Size = new System.Drawing.Size(13, 13);
            this.labPrevMonth.TabIndex = 1;
            this.labPrevMonth.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            this.labPrevMonth.Click += new System.EventHandler(this.LabPrevYear_Click);
            this.labPrevMonth.MouseEnter += new System.EventHandler(this.LabPrevYear_MouseEnter);
            this.labPrevMonth.MouseLeave += new System.EventHandler(this.LabPrevYear_MouseLeave);
            // 
            // labNextMonth
            // 
            this.labNextMonth.Image = ((System.Drawing.Image)(resources.GetObject("labNextMonth.Image")));
            this.labNextMonth.Location = new System.Drawing.Point(144, 5);
            this.labNextMonth.Name = "labNextMonth";
            this.labNextMonth.Size = new System.Drawing.Size(13, 13);
            this.labNextMonth.TabIndex = 2;
            this.labNextMonth.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            this.labNextMonth.Click += new System.EventHandler(this.LabPrevYear_Click);
            this.labNextMonth.MouseEnter += new System.EventHandler(this.LabPrevYear_MouseEnter);
            this.labNextMonth.MouseLeave += new System.EventHandler(this.LabPrevYear_MouseLeave);
            // 
            // labNextYear
            // 
            this.labNextYear.Image = ((System.Drawing.Image)(resources.GetObject("labNextYear.Image")));
            this.labNextYear.Location = new System.Drawing.Point(162, 5);
            this.labNextYear.Name = "labNextYear";
            this.labNextYear.Size = new System.Drawing.Size(13, 13);
            this.labNextYear.TabIndex = 3;
            this.labNextYear.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            this.labNextYear.Click += new System.EventHandler(this.LabPrevYear_Click);
            this.labNextYear.MouseEnter += new System.EventHandler(this.LabPrevYear_MouseEnter);
            this.labNextYear.MouseLeave += new System.EventHandler(this.LabPrevYear_MouseLeave);
            // 
            // labCurrentDate
            // 
            this.labCurrentDate.Location = new System.Drawing.Point(41, 5);
            this.labCurrentDate.Name = "labCurrentDate";
            this.labCurrentDate.Size = new System.Drawing.Size(98, 13);
            this.labCurrentDate.TabIndex = 4;
            this.labCurrentDate.Text = "2020年12月";
            this.labCurrentDate.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // labSelectedDate
            // 
            this.labSelectedDate.Location = new System.Drawing.Point(0, 162);
            this.labSelectedDate.Name = "labSelectedDate";
            this.labSelectedDate.Size = new System.Drawing.Size(180, 18);
            this.labSelectedDate.TabIndex = 5;
            this.labSelectedDate.Text = "label2";
            this.labSelectedDate.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // xwMonthCalendar
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.Controls.Add(this.labSelectedDate);
            this.Controls.Add(this.labCurrentDate);
            this.Controls.Add(this.labNextMonth);
            this.Controls.Add(this.labNextYear);
            this.Controls.Add(this.labPrevMonth);
            this.Controls.Add(this.labPrevYear);
            this.Name = "xwMonthCalendar";
            this.Size = new System.Drawing.Size(180, 180);
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Label labPrevYear;
        private System.Windows.Forms.Label labPrevMonth;
        private System.Windows.Forms.Label labNextMonth;
        private System.Windows.Forms.Label labNextYear;
        private System.Windows.Forms.Label labCurrentDate;
        private System.Windows.Forms.Label labSelectedDate;
    }
}

xwMonthCalendar.resx

<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  <data name="labPrevYear.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
    <value>
        iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAYAAACALL/6AAAABGdBTUEAALGPC/xhBQAAAF9JREFUKFNj
        QAe2UVHutuHhr4C0GVQIqxgYDBLF9pGRvrYREQ8co6KMoUJYxeDAPjraFGSSQ2SkB1QIqxgKoK8mu4iI
        1yAPQ4WwiqEAh6goA7vw8EuOkZH2UCEksUh7AHi0U/vJvVWtAAAAAElFTkSuQmCC
</value>
  </data>
  <data name="labPrevMonth.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
    <value>
        iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAABGdBTUEAALGPC/xhBQAAAF1JREFUKFNj
        QAe2UVFmdhERJVAuBIAEbcPDXzmFhytDhRCCQNodKoRD0DkyUhxDEARsIyLu2EdGZkG5CGAfEWEL0uEQ
        GekBFUIA++hoU/IlgZ57jeEQEAC7MiIiAwAzQymHZBUrOQAAAABJRU5ErkJggg==
</value>
  </data>
  <data name="labNextMonth.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
    <value>
        iVBORw0KGgoAAAANSUhEUgAAAAYAAAAKCAYAAACXDi8zAAAABGdBTUEAALGPC/xhBQAAAEdJREFUGFdj
        sIuI2ADE6xwaGlgYkAFIgAaSoatWMduGhy+3jYhYBhWCAN+0NC6gxBG78PAZUCGKBUEAKLge6JK5UC4U
        MDAAALD7LxOFqPajAAAAAElFTkSuQmCC
</value>
  </data>
  <data name="labNextYear.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
    <value>
        iVBORw0KGgoAAAANSUhEUgAAAAwAAAALCAYAAABLcGxfAAAABGdBTUEAALGPC/xhBQAAAI5JREFUKFNj
        sI2MDLYPD89MS0tjZYACbGIowDYiYpZdePhBt9hYbqgQVjEUAFYQEXHINy2NCyqEVQwFAJ0xG2QqsgJs
        YigArCAi4jSGJjQxOAAJ2oaH/3OOjBSHCmEVAwOQBMh6kIlQIaxiYECS4tDCQk50CWxicAD0UDe6BDYx
        OABKToYy4QCbGAMDAwMAcAFVx/DrCbkAAAAASUVORK5CYII=
</value>
  </data>
</root>

需要拖到窗体上使用,对应文件.cs/.Designer.cs
xwDateTimePicker.cs

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

namespace xwDateTimePicker.DateTimePicker
{
    [ToolboxItem(true)]
    public partial class xwDateTimePicker : UserControl
    {
        private int _Radius = 1;

        public int Radius
        {
            get { return _Radius; }
            set
            {
                if (value < 1) { throw new ArgumentOutOfRangeException(); }
                _Radius = value;
                this.Invalidate();
            }
        }
        private DateTime _value = DateTime.Now;

        public DateTime Value
        {
            get
            {
                _value = new DateTime(txtYear.Text.ToInt(2020), txtMonth.Text.ToInt(1), txtDay.Text.ToInt(1),
                    txtHour.Text.ToInt(1), txtMinite.Text.ToInt(1), txtSecond.Text.ToInt(1));
                Year = _value.Year;
                Month = _value.Month;
                Day = _value.Day;
                txtHour.Text = _value.Hour.ToString("00");
                txtMinite.Text = _value.Minute.ToString("00");
                txtSecond.Text = _value.Second.ToString("00");
                return _value;
            }
            set
            {
                Year = value.Year;
                Month = value.Month;
                Day = value.Day;
                txtHour.Text = value.Hour.ToString("00");
                txtMinite.Text = value.Minute.ToString("00");
                txtSecond.Text = value.Second.ToString("00");
                _value = value;
            }
        }
        enum SelectType
        {
            Year = 0,
            Month = 1,
            Day = 2,
            Hour = 3,
            Minute = 4,
            Second = 5
        }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
        public int Year
        {
            set { txtYear.Text = value + ""; }
        }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
        public int Month
        {
            set
            {
                if (value < 1 || value > 12) { throw new ArgumentOutOfRangeException("月份范围是1至12."); }
                txtMonth.Text = value.ToString("d2");
            }
        }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
        public int Day
        {
            set
            {
                if (value < 1 || value > 31) { throw new ArgumentOutOfRangeException("日期范围是1至31."); }
                txtDay.Text = value.ToString("d2");
            }
        }

        public xwDateTimePicker()
        {
            InitializeComponent();
            this.SetStyle(
           ControlStyles.UserPaint |  //控件自行绘制,而不使用操作系统的绘制
           ControlStyles.AllPaintingInWmPaint | //忽略擦出的消息,减少闪烁。
           ControlStyles.OptimizedDoubleBuffer |//在缓冲区上绘制,不直接绘制到屏幕上,减少闪烁。
           ControlStyles.ResizeRedraw | //控件大小发生变化时,重绘。                  
           ControlStyles.SupportsTransparentBackColor, true);//支持透明背景颜色


            txtYear.GotFocus += txtYear_GotFocus;
            txtMonth.GotFocus += txtYear_GotFocus;
            txtDay.GotFocus += txtYear_GotFocus;
            txtHour.GotFocus += txtYear_GotFocus;
            txtMinite.GotFocus += txtYear_GotFocus;
            txtSecond.GotFocus += txtYear_GotFocus;

            txtYear.Click += txtYear_GotFocus;
            txtMonth.Click += txtYear_GotFocus;
            txtDay.Click += txtYear_GotFocus;
            txtHour.Click += txtYear_GotFocus;
            txtMinite.Click += txtYear_GotFocus;
            txtSecond.Click += txtYear_GotFocus;

            txtYear.KeyDown += txtYear_KeyDown;
            txtMonth.KeyDown += txtYear_KeyDown;
            txtDay.KeyDown += txtYear_KeyDown;
            txtHour.KeyDown += txtYear_KeyDown;
            txtMinite.KeyDown += txtYear_KeyDown;
            txtSecond.KeyDown += txtYear_KeyDown;
            Value = DateTime.Now;
            RefershBack();
            this.BackColorChanged += delegate { RefershBack(); };
        }

        /// <summary>选择面板是否已经打开</summary>
        bool _dropDownShow = false;
        xwMonthCalendar _skinMonthCalendar;
        ToolStripDropDown _dropDown;
        private void txtYear_MouseDown(object sender, MouseEventArgs e)
        {
            if (!_dropDownShow)
            {
                _dropDownShow = true;
                _skinMonthCalendar = new xwMonthCalendar(this);

                _dropDown = new ToolStripDropDown() { Padding = Padding.Empty, Margin = Padding.Empty };
                _dropDown.Items.Add(new ToolStripControlHost(_skinMonthCalendar) { AutoSize = false, Padding = Padding.Empty, Margin = Padding.Empty });
                _dropDown.Show(this, new Point(0, this.Height));
                _dropDown.Closed += (s1, e1) => { _dropDownShow = false; };
            }
            else
            {
                _dropDownShow = false;
                DropDownClose();
            }
        }


        public void DropDownClose()
        {
            if (_dropDown != null) { if (!_dropDown.IsDisposed) { _dropDown.Close(); } }
            _skinMonthCalendar = null;
        }

        private void RefershBack()
        {
            if (this.BackColor == Color.Transparent)
            {
                txtHour.BackColor = txtMinite.BackColor = txtSecond.BackColor
                    = txtMonth.BackColor = txtDay.BackColor = txtYear.BackColor = Color.White;
            }
            else
            {
                txtHour.BackColor = txtMinite.BackColor = txtSecond.BackColor
                                  = txtMonth.BackColor = txtDay.BackColor = txtYear.BackColor = this.BackColor;
            }
        }

        void txtYear_KeyDown(object sender, KeyEventArgs e)
        {
            e.SuppressKeyPress = false;
            if (!(sender is TextBox _TextBox))
            {
                return;
            }
            string _txt = _TextBox.Text;
            SelectType _selected = SelectType.Year;
            switch (_TextBox.Name)
            {
                case "txtYear":
                    _selected = SelectType.Year;
                    break;
                case "txtMonth":
                    _selected = SelectType.Month;
                    break;
                case "txtDay":
                    _selected = SelectType.Day;
                    break;
                case "txtHour":
                    _selected = SelectType.Hour;
                    break;
                case "txtMinite":
                    _selected = SelectType.Minute;
                    break;
                case "txtSecond":
                    _selected = SelectType.Second;
                    break;
                default:
                    break;
            }

            if (e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9)
            {

            }
            else if (e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9)
            {
            }
            else if ((Keys)e.KeyValue == Keys.Delete)
            {
                if (_TextBox.SelectionLength > 0)
                {
                    _txt = _TextBox.Text.Substring(0, _TextBox.SelectionStart) + _TextBox.Text.Substring(_TextBox.SelectionStart + _TextBox.SelectionLength);
                }
                else if (_TextBox.SelectionStart >= 0)
                {
                    int _index = _TextBox.Text.Length - _TextBox.SelectionStart - 1;
                    _index = _index < 0 ? 0 : _index;
                    _txt = _txt.Substring(0, _TextBox.SelectionStart) + _txt.Substring(_TextBox.SelectionStart, _index);
                }
                _TextBox.Text = _txt;
                _TextBox.SelectionStart = _txt.Length;
                return;
            }
            else if ((Keys)e.KeyValue == Keys.Back)
            {
                if (_TextBox.SelectionLength > 0)
                {
                    _txt = _TextBox.Text.Substring(0, _TextBox.SelectionStart) + _TextBox.Text.Substring(_TextBox.SelectionStart + _TextBox.SelectionLength);
                }
                else if (_TextBox.SelectionStart >= 0)
                {
                    int _index = _TextBox.SelectionStart - 1;
                    _index = _index < 0 ? 0 : _index;
                    _txt = _txt.Substring(0, _index) + _txt.Substring(_TextBox.SelectionStart);
                }
                _TextBox.Text = _txt;
                _TextBox.SelectionStart = _txt.Length;
                return;
            }
            else
            {
                return;
            }
            if (_TextBox.SelectionLength > 0)
            {
                _txt = _txt.Substring(0, _TextBox.SelectionStart) + KeyName(e.KeyCode) + _txt.Substring(_TextBox.SelectionStart + _TextBox.SelectedText.Length);
            }
            else
            {
                if (_TextBox.SelectionStart >= 0)
                {
                    _txt = _txt.Substring(0, _TextBox.SelectionStart) + KeyName(e.KeyCode) + _txt.Substring(_TextBox.SelectionStart);
                }
                else
                {
                    _txt = _txt.Substring(0, _TextBox.SelectionStart) + KeyName(e.KeyCode);
                }

            }
            switch (_selected)
            {
                case SelectType.Year:
                    if (_txt.ToInt(0) > 0 && _txt.ToInt(0) < 9999)
                    { }
                    else
                    {
                        return;
                    }
                    break;
                case SelectType.Month:
                    if (_txt.ToInt(0) >= 0 && _txt.ToInt(0) <= 12)
                    { }
                    else
                    {
                        return;
                    }
                    break;
                case SelectType.Day:
                    DateTime dt = new DateTime(txtYear.Text.ToInt(1), txtMonth.Text.ToInt(1), 1, 0, 0, 0);
                    dt = dt.AddMonths(1).AddSeconds(-10);
                    int _Day = dt.Day;
                    if (_txt.ToInt(0) >= 0 && _txt.ToInt(0) <= _Day)
                    { }
                    else
                    {
                        return;
                    }
                    break;
                case SelectType.Hour:
                    if (_txt.ToInt(0) >= 0 && _txt.ToInt(0) < 24)
                    { }
                    else
                    {
                        return;
                    }
                    break;
                case SelectType.Minute:
                case SelectType.Second:
                    if (_txt.ToInt(0) >= 0 && _txt.ToInt(0) < 59)
                    { }
                    else
                    {
                        return;
                    }
                    break;
                default:
                    break;
            }
            _TextBox.Text = _txt;
            _TextBox.SelectionStart = _txt.Length;
        }

        char KeyName(Keys keycode)
        {
            if (keycode >= Keys.NumPad0 && keycode <= Keys.NumPad9)
            {
                char cc;
                switch (keycode)
                {
                    case Keys.NumPad0:
                    case Keys.D0:
                        cc = '0';
                        break;
                    case Keys.NumPad1:
                    case Keys.D1:
                        cc = '1';
                        break;
                    case Keys.NumPad2:
                    case Keys.D2:
                        cc = '2';
                        break;
                    case Keys.NumPad3:
                    case Keys.D3:
                        cc = '3';
                        break;
                    case Keys.NumPad4:
                    case Keys.D4:
                        cc = '4';
                        break;
                    case Keys.NumPad5:
                    case Keys.D5:
                        cc = '5';
                        break;
                    case Keys.NumPad6:
                    case Keys.D6:
                        cc = '6';
                        break;
                    case Keys.NumPad7:
                    case Keys.D7:
                        cc = '7';
                        break;
                    case Keys.NumPad8:
                    case Keys.D8:
                        cc = '8';
                        break;
                    case Keys.NumPad9:
                    case Keys.D9:
                        cc = '9';
                        break;
                    default: cc = ' '; break;
                }
                return cc;
            }
            else
            {
                return (char)keycode;
            }
        }

        void txtYear_GotFocus(object sender, EventArgs e)
        {
            if (sender is TextBox _txt)
            {
                _txt.SelectAll();
            }
        }

        protected override void OnForeColorChanged(EventArgs e)
        {
            base.OnForeColorChanged(e);
            txtSecond.ForeColor = txtMinite.ForeColor = txtHour.ForeColor = txtDay.ForeColor
                = txtMonth.ForeColor = txtYear.ForeColor = this.ForeColor;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            base.OnPaintBackground(e);
            e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
            e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
            e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;

            #region 根据内容和字体计算控件大小和位置

            this.Height = txtYear.ClientSize.Height * 2;
            int _locationY = (this.Height - txtYear.Height) / 2;
            _locationY = _locationY > 0 ? _locationY : 0;

            txtSecond.Font = txtMinite.Font = txtHour.Font = txtDay.Font = txtMonth.Font = txtYear.Font = this.Font;

            int widthHangxian = (int)e.Graphics.MeasureString("-", Font).Width;
            int widthMaohao = (int)e.Graphics.MeasureString(":", Font).Width;

            txtYear.Size = txtYear.PreferredSize;
            txtMonth.Size = txtMonth.PreferredSize;
            txtDay.Size = txtDay.PreferredSize;
            txtHour.Size = txtHour.PreferredSize;
            txtMinite.Size = txtMinite.PreferredSize;
            txtSecond.Size = txtSecond.PreferredSize;

            txtYear.Location = new Point(10, _locationY);
            txtMonth.Location = new Point(txtYear.Right + widthHangxian, _locationY);
            txtDay.Location = new Point(txtMonth.Right + widthHangxian, _locationY);
            txtHour.Location = new Point(txtDay.Right + 10, _locationY);
            txtMinite.Location = new Point(txtHour.Right + widthMaohao, _locationY);
            txtSecond.Location = new Point(txtMinite.Right + widthMaohao, _locationY);

            this.Width = txtSecond.Right + 10;
            #endregion
            Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);
            var path = GetRoundedRectPath(rect, _Radius);

            this.Region = new Region(path);

            try
            {
                Graphics _Graphics = e.Graphics;
                {
                    using (SolidBrush b = new SolidBrush(BackColor))
                    {
                        _Graphics.FillPath(b, path);
                    }

                    SolidBrush _brush = new SolidBrush(txtYear.ForeColor);

                    int _widthLeft = 0;

                    //年和月之间的-
                    _Graphics.DrawString("-", Font, _brush, new PointF(_widthLeft + txtYear.Bounds.Right, _locationY));
                    _Graphics.DrawString("-", Font, _brush, new PointF(_widthLeft + txtMonth.Bounds.Right, _locationY));

                    //小时和分钟之间的:
                    _Graphics.DrawString(":", Font, _brush, new PointF(_widthLeft + txtHour.Bounds.Right, _locationY));
                    _Graphics.DrawString(":", Font, _brush, new PointF(_widthLeft + txtMinite.Bounds.Right, _locationY));
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
        GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
        {
            if (radius <= 0) { radius = 1; }

            int diameter = radius;
            Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
            GraphicsPath path = new GraphicsPath();
            path.AddArc(arcRect, 180, 90);
            arcRect.X = rect.Right - diameter;
            path.AddArc(arcRect, 270, 90);
            arcRect.Y = rect.Bottom - diameter;
            path.AddArc(arcRect, 0, 90);
            arcRect.X = rect.Left;
            path.AddArc(arcRect, 90, 90);
            path.CloseFigure();
            return path;
        }
    }
}

xwDateTimePicker.Designer.cs

namespace xwDateTimePicker.DateTimePicker
{
    partial class xwDateTimePicker
    {
        /// <summary> 
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary> 
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region 组件设计器生成的代码

        /// <summary> 
        /// 设计器支持所需的方法 - 不要修改
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.txtYear = new System.Windows.Forms.TextBox();
            this.txtMonth = new System.Windows.Forms.TextBox();
            this.txtDay = new System.Windows.Forms.TextBox();
            this.txtHour = new System.Windows.Forms.TextBox();
            this.txtMinite = new System.Windows.Forms.TextBox();
            this.txtSecond = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // txtYear
            // 
            this.txtYear.BackColor = System.Drawing.Color.White;
            this.txtYear.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.txtYear.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
            this.txtYear.Location = new System.Drawing.Point(10, 22);
            this.txtYear.Margin = new System.Windows.Forms.Padding(0);
            this.txtYear.Name = "txtYear";
            this.txtYear.ReadOnly = true;
            this.txtYear.Size = new System.Drawing.Size(29, 16);
            this.txtYear.TabIndex = 0;
            this.txtYear.Text = "2020";
            this.txtYear.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            this.txtYear.MouseDown += new System.Windows.Forms.MouseEventHandler(this.txtYear_MouseDown);
            // 
            // txtMonth
            // 
            this.txtMonth.BackColor = System.Drawing.Color.White;
            this.txtMonth.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.txtMonth.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
            this.txtMonth.Location = new System.Drawing.Point(49, 22);
            this.txtMonth.Margin = new System.Windows.Forms.Padding(0);
            this.txtMonth.Name = "txtMonth";
            this.txtMonth.ReadOnly = true;
            this.txtMonth.Size = new System.Drawing.Size(17, 16);
            this.txtMonth.TabIndex = 1;
            this.txtMonth.Text = "12";
            this.txtMonth.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            this.txtMonth.MouseDown += new System.Windows.Forms.MouseEventHandler(this.txtYear_MouseDown);
            // 
            // txtDay
            // 
            this.txtDay.BackColor = System.Drawing.Color.White;
            this.txtDay.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.txtDay.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
            this.txtDay.Location = new System.Drawing.Point(76, 22);
            this.txtDay.Margin = new System.Windows.Forms.Padding(0);
            this.txtDay.Name = "txtDay";
            this.txtDay.ReadOnly = true;
            this.txtDay.Size = new System.Drawing.Size(17, 16);
            this.txtDay.TabIndex = 2;
            this.txtDay.Text = "26";
            this.txtDay.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            this.txtDay.MouseDown += new System.Windows.Forms.MouseEventHandler(this.txtYear_MouseDown);
            // 
            // txtHour
            // 
            this.txtHour.BackColor = System.Drawing.Color.White;
            this.txtHour.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.txtHour.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
            this.txtHour.Location = new System.Drawing.Point(103, 22);
            this.txtHour.Margin = new System.Windows.Forms.Padding(0);
            this.txtHour.Name = "txtHour";
            this.txtHour.ReadOnly = true;
            this.txtHour.Size = new System.Drawing.Size(17, 16);
            this.txtHour.TabIndex = 3;
            this.txtHour.Text = "18";
            this.txtHour.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            // 
            // txtMinite
            // 
            this.txtMinite.BackColor = System.Drawing.Color.White;
            this.txtMinite.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.txtMinite.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
            this.txtMinite.Location = new System.Drawing.Point(130, 22);
            this.txtMinite.Margin = new System.Windows.Forms.Padding(0);
            this.txtMinite.Name = "txtMinite";
            this.txtMinite.ReadOnly = true;
            this.txtMinite.Size = new System.Drawing.Size(17, 16);
            this.txtMinite.TabIndex = 4;
            this.txtMinite.Text = "41";
            this.txtMinite.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            // 
            // txtSecond
            // 
            this.txtSecond.BackColor = System.Drawing.Color.White;
            this.txtSecond.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.txtSecond.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
            this.txtSecond.Location = new System.Drawing.Point(157, 22);
            this.txtSecond.Margin = new System.Windows.Forms.Padding(0);
            this.txtSecond.Name = "txtSecond";
            this.txtSecond.ReadOnly = true;
            this.txtSecond.Size = new System.Drawing.Size(17, 16);
            this.txtSecond.TabIndex = 5;
            this.txtSecond.Text = "00";
            this.txtSecond.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            // 
            // xwDateTimePicker
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.BackColor = System.Drawing.Color.Transparent;
            this.Controls.Add(this.txtSecond);
            this.Controls.Add(this.txtMinite);
            this.Controls.Add(this.txtHour);
            this.Controls.Add(this.txtDay);
            this.Controls.Add(this.txtMonth);
            this.Controls.Add(this.txtYear);
            this.Margin = new System.Windows.Forms.Padding(0);
            this.Name = "xwDateTimePicker";
            this.Size = new System.Drawing.Size(184, 88);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.TextBox txtYear;
        private System.Windows.Forms.TextBox txtMonth;
        private System.Windows.Forms.TextBox txtDay;
        private System.Windows.Forms.TextBox txtHour;
        private System.Windows.Forms.TextBox txtMinite;
        private System.Windows.Forms.TextBox txtSecond;
    }
}

需要用到的扩展类

public static class Extension
  {
      /// <summary>指定值为int的string对象转换为对应的int对象</summary>
      /// <param name="o"></param>
      /// <param name="_default"></param>
      /// <returns></returns>
      public static int ToInt(this string o, int _default = 0)
      {
          int _tmp = _default;
          int.TryParse(o, out _tmp);
          return _tmp;
      }
  }

最后来张效果图,顺便打包代码自定义日历控件

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: C# WinForm
最后更新:2020-12-27

cxw

技术宅,最喜瞎折腾.

点赞
< 上一篇
下一篇 >
最新 热点 随机
最新 热点 随机
git迁移项目中的某个目录到新项目 winform判断设计模式还是运行时模式 C# 中的where T : class, new() 到底是什么意思? 解决安装.NET失败并提示“无法建立到信任根颁发机构的证书链” 关闭.net4.0的http访问默认代理 删除名称最后带空格的文件夹
WinAPI GetLastError() 返回值对照表 2022年夏天前最后一场雪? SQL Server 附加数据库出错,操作系统错误 5:"5(拒绝访问。)" 错误:5120 C# 获取json中的某一属性值 WordPress5.5版本如何使用自带站点地图sitemap 英文字体设计1
标签聚合
WinForm 工具 PHP C# W10 IT Linux Excel WordPress CentOS
最近评论
admin 发布于 4 年前(01月22日) 使用Andi Dittrich作者的插件Enlighter实现
alex 发布于 4 年前(01月22日) 博主,请问把代码贴到博客里可以复制是怎么实现的

COPYRIGHT © 2021 十字星. ALL RIGHTS RESERVED

Theme Kratos Made By Seaton Jiang