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