原生控件领导觉得不好看要求重写,因此有了这篇文章,先上关键代码,以后有时间了在具体说明
自定义日历选择的弹出控件,对应文件.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>
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; } }
文章评论