C# 自定义控件,日期时间选择输入插件
2016-06-14 18:12
603 查看
// 为textBox1添加一个日期时间选择控件 DateTimeChoser.AddTo(textBox1);
DateTimeChoser.Designer.cs
using System; using System.ComponentModel; using System.Drawing; using System.Reflection; using System.Windows.Forms; namespace pictureAnalyse { /// <summary> /// 此类用于实现一个日期时间辅助输入插件,调用逻辑: /// new DateTimeChoser(textBox1); //即可为textBox1绑定一个日期时间输入控件 /// </summary> public partial class DateTimeChoser : UserControl { public static bool showConfirmButton = true; // 日期时间选择时,是否显示确定按钮 /// <summary> /// 为textBoox添加一个日期时间选择控件,辅助日期时间的输入 /// </summary> public static void AddTo(TextBox textBox) { try { DateTime time = DateTime.Parse(textBox.Text); } catch (Exception ex) { textBox.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); } textBox.MouseClick += textBoox_MouseClick; } /// <summary> /// 为textBoox添加一个日期时间选择控件,辅助日期时间的输入,并设置初始时显示的时间 /// </summary> public static void AddTo(TextBox textBoox, DateTime dateTime) { textBoox.Text = dateTime.ToString("yyyy-MM-dd HH:mm:ss"); textBoox.MouseClick += textBoox_MouseClick; } private static void textBoox_MouseClick(object sender, MouseEventArgs e) { TextBox textBox = sender as TextBox; // 创建一个关联到textBox的日期时间选择控件 DateTimeChoser choser = new DateTimeChoser(); choser.showOn(textBox); // 设置显示的时间为文本框中的日期时间 try { DateTime time = DateTime.Parse(textBox.Text); choser.setDateTime(time); } catch (Exception ex) { } } public DateTimeChoser() { InitializeComponent(); init(); } private void init() { // 时分秒设置 for (int i = 0; i < 24; i++) comboBox_hour.Items.Add((i < 10 ? "0" : "") + i); for (int i = 0; i < 60; i = i + 1) comboBox_minite.Items.Add((i < 10 ? "0" : "") + i); for (int i = 0; i < 60; i++) comboBox_second.Items.Add((i < 10 ? "0" : "") + i); comboBox_hour.DropDownStyle = ComboBoxStyle.DropDownList; comboBox_minite.DropDownStyle = ComboBoxStyle.DropDownList; comboBox_second.DropDownStyle = ComboBoxStyle.DropDownList; //设置显示的日期时间 setDateTime(DateTime.Now); } public delegate void DateTimeChanged_Handle(object sender, EventArgs e); [Description("当选择日期或时间变动时,调用此事件"), Category("自定义事件")] public event DateTimeChanged_Handle DateTimeChanged; // 选择日期变动 private void monthCalendar1_DateSelected(object sender, DateRangeEventArgs e) { DateTime S = monthCalendar1.SelectionStart; string date = S.ToString("yyyy-MM-dd"); if (!date.Equals(label_date.Text)) { label_date.Text = date; if (DateTimeChanged != null) DateTimeChanged(this, new EventArgs()); } } //选择的时间变动 private void TimeChanged(object sender, EventArgs e) { string time = comboBox_hour.Text + ":" + comboBox_minite.Text + ":" + comboBox_second.Text; if (!time.Equals(label_time.Text)) { label_time.Text = time; if (DateTimeChanged != null) DateTimeChanged(this, new EventArgs()); } } // 设置显示到指定的日期时间 public void setDateTime(DateTime now) { // 初始时界面显示当前的日期时间 label_date.Text = now.ToString("yyyy-MM-dd"); monthCalendar1.SetDate(now); // 设置时间 label_time.Text = now.ToString("HH:mm:ss"); comboBox_hour.SelectedIndex = now.Hour; comboBox_minite.SelectedIndex = now.Minute; comboBox_second.SelectedIndex = now.Second; } // 获取当前选择的日期时间 public string getDateTime() { return label_date.Text + " " + label_time.Text; } # region 自定义控件输入绑定逻辑,将当前日期时间控件绑定到指定的TextBox private Form form; TextBox textbox; private Delegate[] textboxEvents; // 在指定的TextBox中,显示当前日期时间选择控件,进行日期时间的输入 public void showOn(TextBox textBox, int offX = 0, int offY = 0) { Point P = getLocation(textBox); P = new Point(P.X, P.Y + textBox.Height); show(textBox, P.X + offX, P.Y + offY, showConfirmButton); } // 在TextBox点击时,调用DateTimeChoser进行日期时间的选择,当再次点击时,关闭之前的日期选择状态 private void show(TextBox textbox, int L, int T, bool showButton) { this.textbox = textbox; textboxEvents = getEvents(textbox, "MouseClick"); // 获取TextBox原有事件处理逻辑 ClearEvent(textbox, "MouseClick"); // 移除TextBox原有MouseClick事件处理逻辑 // 新建一个窗体 form = new Form(); form.Width = this.Width; form.Height = this.Height; if (showButton) form.Height = this.Height + 40; form.FormBorderStyle = FormBorderStyle.None; // 无边框 form.ShowInTaskbar = false; // 不在任务栏中显示 form.BackColor = Color.White; // form.Location = new Point(L, T); // 将当前日期时间选择控件添加到form中 this.Left = 0; this.Top = 0; form.Controls.Add(this); if (showButton) { Button button = new Button(); button.Text = "确定"; button.ForeColor = Color.Blue; button.Left = (this.Width - button.Width) / 2; button.Top = this.Height + (40 - button.Height) / 2; form.Controls.Add(button); button.Click += button_Click; } form.Show(); // 显示日期时间选择 form.Location = new Point(L, T); form.TopMost = true; form.Activate(); // 当前界面获取到焦点 Form Parent = getParentForm(textbox); // 获取TextBox的父窗体 if (Parent != null) Parent.FormClosed += Parent_FormClosed; textbox.MouseClick += textbox_MouseClick; } // 添加 private void button_Click(object sender, EventArgs e) { textbox_MouseClick(textbox, null); } // 关闭当前form private void Parent_FormClosed(object sender, FormClosedEventArgs e) { if (form != null) { form.Close(); form = null; } } private void textbox_MouseClick(object sender, MouseEventArgs e) { TextBox textBox = sender as TextBox; textBox.Text = getDateTime(); if (form != null) { form.Close(); form = null; } textBox.MouseClick -= textbox_MouseClick; // 移除当前事件处理逻辑 addEvents(textBox, "MouseClick", textboxEvents); // 还原TextBox原有事件处理逻辑 } # endregion // 获取给定控件的父窗体 public static Form getParentForm(Control control) { if (control is Form) return control as Form; Control C = control; while (C.Parent != null) { if (C.Parent is Form) return C.Parent as Form; else C = C.Parent; } return null; } #region 获取控件的坐标信息 /// <summary> /// 获取任意控件相对于屏幕的坐标 /// </summary> public static Point getLocation(Control control) { Point P; if (control is Form) P = getFormClientLocation(control as Form); else P = control.Location; if (control.Parent != null) { Control parent = control.Parent; Point P2 = getLocation(parent); P = new Point(P.X + P2.X, P.Y + P2.Y); } return P; } /// <summary> /// 获取Form窗体有效显示区域的起点,相对于屏幕的坐标 /// </summary> public static Point getFormClientLocation(Form form) { Rectangle rect = form.ClientRectangle; int offx = 0, offy = 0; if (form.FormBorderStyle != FormBorderStyle.None) { offx = (form.Width - rect.Width) / 2; offy = (form.Height - rect.Height) - 8; } Point P = new Point(form.Location.X + offx, form.Location.Y + offy); return P; } # endregion # region 动态修改控件对应的事件处理逻辑 // ClearEvent(button1,"Click");//就会清除button1对象的Click事件的所有挂接事件。 private void ClearEvent(Control control, string eventname) { if (control == null) return; if (string.IsNullOrEmpty(eventname)) return; BindingFlags mPropertyFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic; BindingFlags mFieldFlags = BindingFlags.Static | BindingFlags.NonPublic; Type controlType = typeof(System.Windows.Forms.Control); PropertyInfo propertyInfo = controlType.GetProperty("Events", mPropertyFlags); EventHandlerList eventHandlerList = (EventHandlerList)propertyInfo.GetValue(control, null); FieldInfo fieldInfo = (typeof(Control)).GetField("Event" + eventname, mFieldFlags); Delegate d = eventHandlerList[fieldInfo.GetValue(control)]; if (d == null) return; EventInfo eventInfo = controlType.GetEvent(eventname); foreach (Delegate dx in d.GetInvocationList()) eventInfo.RemoveEventHandler(control, dx); } // getEvent(button1,"Click"); //就会获取到button1对象的Click事件的所有挂接事件。 private Delegate[] getEvents(Control control, string eventname) { if (control == null) return null; if (string.IsNullOrEmpty(eventname)) return null; BindingFlags mPropertyFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic; BindingFlags mFieldFlags = BindingFlags.Static | BindingFlags.NonPublic; Type controlType = typeof(System.Windows.Forms.Control); PropertyInfo propertyInfo = controlType.GetProperty("Events", mPropertyFlags); EventHandlerList eventHandlerList = (EventHandlerList)propertyInfo.GetValue(control, null); FieldInfo fieldInfo = (typeof(Control)).GetField("Event" + eventname, mFieldFlags); Delegate d = eventHandlerList[fieldInfo.GetValue(control)]; if (d == null) return null; Delegate[] events = new Delegate[d.GetInvocationList().Length]; int i = 0; foreach (Delegate dx in d.GetInvocationList()) events[i++] = dx; return events; } // addEvents(button1,"Click"); // 为button1对象的Click事件挂接事件 private void addEvents(Control control, string eventname, Delegate[] evenets) { if (control == null) return; if (string.IsNullOrEmpty(eventname)) return; Type controlType = typeof(System.Windows.Forms.Control); EventInfo eventInfo = controlType.GetEvent(eventname); foreach (Delegate e in evenets) eventInfo.AddEventHandler(control, e); } # endregion } }
DateTimeChoser.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace pictureAnalyse { partial class DateTimeChoser { /// <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.monthCalendar1 = new System.Windows.Forms.MonthCalendar(); this.panel_consume = new System.Windows.Forms.Panel(); this.label6 = new System.Windows.Forms.Label(); this.comboBox_second = new System.Windows.Forms.ComboBox(); this.label5 = new System.Windows.Forms.Label(); this.comboBox_minite = new System.Windows.Forms.ComboBox(); this.label4 = new System.Windows.Forms.Label(); this.comboBox_hour = new System.Windows.Forms.ComboBox(); this.panel1 = new System.Windows.Forms.Panel(); this.label_date = new System.Windows.Forms.Label(); this.label_time = new System.Windows.Forms.Label(); this.panel2 = new System.Windows.Forms.Panel(); this.panel_consume.SuspendLayout(); this.panel1.SuspendLayout(); this.panel2.SuspendLayout(); this.SuspendLayout(); // // monthCalendar1 // this.monthCalendar1.AllowDrop = true; this.monthCalendar1.Location = new System.Drawing.Point(-3, 15); this.monthCalendar1.Name = "monthCalendar1"; this.monthCalendar1.TabIndex = 0; this.monthCalendar1.DateSelected += new System.Windows.Forms.DateRangeEventHandler(this.monthCalendar1_DateSelected); // // panel_consume // this.panel_consume.BackColor = System.Drawing.Color.White; this.panel_consume.Controls.Add(this.label6); this.panel_consume.Controls.Add(this.comboBox_second); this.panel_consume.Controls.Add(this.label5); this.panel_consume.Controls.Add(this.comboBox_minite); this.panel_consume.Controls.Add(this.label4); this.panel_consume.Controls.Add(this.comboBox_hour); this.panel_consume.Location = new System.Drawing.Point(-2, 173); this.panel_consume.Name = "panel_consume"; this.panel_consume.Size = new System.Drawing.Size(222, 30); this.panel_consume.TabIndex = 23; // // label6 // this.label6.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.label6.AutoSize = true; this.label6.Location = new System.Drawing.Point(195, 10); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(17, 12); this.label6.TabIndex = 15; this.label6.Text = "秒"; // // comboBox_second // this.comboBox_second.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.comboBox_second.FormattingEnabled = true; this.comboBox_second.Location = new System.Drawing.Point(149, 6); this.comboBox_second.Name = "comboBox_second"; this.comboBox_second.Size = new System.Drawing.Size(40, 20); this.comboBox_second.TabIndex = 14; this.comboBox_second.Text = "0"; this.comboBox_second.SelectedIndexChanged += new System.EventHandler(this.TimeChanged); // // label5 // this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.label5.AutoSize = true; this.label5.Location = new System.Drawing.Point(126, 10); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(17, 12); this.label5.TabIndex = 13; this.label5.Text = "分"; // // comboBox_minite // this.comboBox_minite.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.comboBox_minite.FormattingEnabled = true; this.comboBox_minite.Location = new System.Drawing.Point(80, 6); this.comboBox_minite.Name = "comboBox_minite"; this.comboBox_minite.Size = new System.Drawing.Size(40, 20); this.comboBox_minite.TabIndex = 12; this.comboBox_minite.Text = "0"; this.comboBox_minite.SelectedIndexChanged += new System.EventHandler(this.TimeChanged); // // label4 // this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.label4.AutoSize = true; this.label4.Location = new System.Drawing.Point(57, 10); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(17, 12); this.label4.TabIndex = 11; this.label4.Text = "时"; // // comboBox_hour // this.comboBox_hour.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.comboBox_hour.FormattingEnabled = true; this.comboBox_hour.Location = new System.Drawing.Point(9, 6); this.comboBox_hour.Name = "comboBox_hour"; this.comboBox_hour.Size = new System.Drawing.Size(42, 20); this.comboBox_hour.TabIndex = 10; this.comboBox_hour.Text = "0"; this.comboBox_hour.SelectedIndexChanged += new System.EventHandler(this.TimeChanged); // // panel1 // this.panel1.BackColor = System.Drawing.Color.White; this.panel1.Controls.Add(this.label_date); this.panel1.Controls.Add(this.label_time); this.panel1.Location = new System.Drawing.Point(-3, -1); this.panel1.Name = "panel1"; this.panel1.Size = new System.Drawing.Size(223, 23); this.panel1.TabIndex = 25; // // label_date // this.label_date.AutoSize = true; this.label_date.BackColor = System.Drawing.Color.White; this.label_date.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); this.label_date.Location = new System.Drawing.Point(18, 3); this.label_date.Name = "label_date"; this.label_date.Size = new System.Drawing.Size(98, 16); this.label_date.TabIndex = 26; this.label_date.Text = "2016-06-12"; // // label_time // this.label_time.AutoSize = true; this.label_time.BackColor = System.Drawing.Color.White; this.label_time.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); this.label_time.Location = new System.Drawing.Point(118, 3); this.label_time.Name = "label_time"; this.label_time.Size = new System.Drawing.Size(80, 16); this.label_time.TabIndex = 25; this.label_time.Text = "12:23:35"; // // panel2 // this.panel2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.panel2.Controls.Add(this.panel1); this.panel2.Controls.Add(this.panel_consume); this.panel2.Controls.Add(this.monthCalendar1); this.panel2.Location = new System.Drawing.Point(0, 0); this.panel2.Name = "panel2"; this.panel2.Size = new System.Drawing.Size(215, 202); this.panel2.TabIndex = 26; // // DateTimeChoser // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.panel2); this.Name = "DateTimeChoser"; this.Size = new System.Drawing.Size(215, 202); this.panel_consume.ResumeLayout(false); this.panel_consume.PerformLayout(); this.panel1.ResumeLayout(false); this.panel1.PerformLayout(); this.panel2.ResumeLayout(false); this.ResumeLayout(false); } #endregion private System.Windows.Forms.MonthCalendar monthCalendar1; private System.Windows.Forms.Panel panel_consume; private System.Windows.Forms.Label label6; private System.Windows.Forms.ComboBox comboBox_second; private System.Windows.Forms.Label label5; private System.Windows.Forms.ComboBox comboBox_minite; private System.Windows.Forms.Label label4; private System.Windows.Forms.ComboBox comboBox_hour; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Label label_date; private System.Windows.Forms.Label label_time; private System.Windows.Forms.Panel panel2; } }
添加以上两个类到项目,编译运行一次。自定义的DateTimeChoser控件会出现在工具箱中。
可直接拖拽至Form窗体中使用,也可通过代码进行调用。
示例下载 pictureAnalyse.exe
示例源码下载 pictureAnalyse.zip
相关文章推荐
- c#调用COM组件
- C#实现把指定数据写入串口
- C#动态创建button的方法
- C#中抽象方法与虚拟方法的区别
- c#中虚函数的相关使用方法
- C#实现给图片加水印的方法
- C#使用加边法计算行列式的值
- C#实现多线程的同步方法实例分析
- C#中尾递归的使用、优化及编译器优化
- C#中的delegate委托类型基本学习教程
- C#实现子窗体与父窗体通信方法实例总结
- C#通用邮件发送类分享
- 举例讲解C#中自动实现的属性
- C#中this的用法集锦
- C#数据结构之顺序表(SeqList)实例详解
- C#.NET获取拨号连接的宽带连接方法
- C#异步绑定数据实现方法
- C#实现AddRange为数组添加多个元素的方法
- C#中Equality和Identity浅析
- C#比较二个数组并找出相同或不同元素的方法