using System;using System.Collections.Generic;using System.ComponentModel;using System.Drawing;using System.Data;using System.Linq;using System.Text;using System.Windows.Forms;namespace test{ public partial class UCL_Datetime : UserControl { /// <summary> /// 自定义日期控件 /// </summary> public UCL_Datetime() { //属性的构造是先于构造函数的 InitializeComponent(); this.ControlAdded = new ControlEventHandler(UCL_Datetime_ControlAdded); } void UCL_Datetime_ControlAdded(object sender, ControlEventArgs e) { textbox_DateTime.Name = this.Name; } MonthCalendar g_month = new MonthCalendar(); #region 属性值设置 bool check_datetime = true; bool textbox_Enabled = true; private string datetime_formate = "yyyy-MM-dd"; //string textbox_text; //string textbox_name; /// <summary> /// 该控件是否已启用 /// </summary> [DefaultValue(""), Description("该控件是否已启用"), Category("Appearance"), Browsable(true)] public bool a_Enabled { get { return textbox_Enabled; } set { textbox_Enabled = value; textbox_DateTime.Enabled = textbox_Enabled; customButton1.Enabled = textbox_Enabled; } } /// <summary> /// 日期控件的值 /// </summary> [DefaultValue(""), Description("日期控件的值"), Category("Appearance"), Browsable(true)] public string a_Text { get { //return textbox_text; return textbox_DateTime.Text; } set { //textbox_text = value; //textbox_DateTime.Text = textbox_text; textbox_DateTime.Text = value; } } /// <summary> /// 光标离开控件时,是否需要判断日期输入的正确性 /// </summary> [DefaultValue("True"), Description("光标离开控件时,是否需要判断日期输入的正确性"), Category("Appearance"), Browsable(true)] public bool a_Check { get { return check_datetime; } set { check_datetime = value; } } /// <summary> /// 日期控件的自定义格式 /// </summary> [DefaultValue(""), Description("日期控件的自定义格式"), Category("Appearance"), Browsable(true)] public string a_Formate { get { return datetime_formate; } set { datetime_formate = value; } } /// <summary> /// 日期控件的名称,与本控件的名称相同,且与对应表的列名相同,隐藏的属性 /// </summary> [DefaultValue(""), Description("日期控件的名称,与本控件的名称相同,且与对应表的列名相同"), Category("Appearance"), Browsable(false)] public string a_textbox_Name { get { return this.Name; } set { textbox_DateTime.Name = value; } } #endregion 属性值设置 /// <summary> /// 日期值改变时的委托 /// </summary> public delegate void Text_Changed(object sender, EventArgs e); /// <summary> /// 日期值改变时的事件 /// </summary> public event Text_Changed TextChanged_event; private void UCL_Datetime_Load(object sender, EventArgs e) { customButton1.Dock = DockStyle.Right; customButton1.FlatStyle = FlatStyle.Popup; customButton1.Width = 21; customButton1.BackColor = Color.Gainsboro; customButton1.BackgroundImageLayout = ImageLayout.Zoom; customButton1.DisplayFocusCues = false; toolTip1.SetToolTip(textbox_DateTime, this.Name); customButton1.Click = new EventHandler(customButton1_Click); g_month.DateSelected = new DateRangeEventHandler(month_DateSelected); g_month.Leave = new EventHandler(month_Leave); //如果使用textbox_DateTime.Validating事件,如果输入的值是错误的,再开窗时会显示错误信息,所以使用this.Validating //this.Validating = new CancelEventHandler(textbox_DateTime_Validating); textbox_DateTime.Validating = new CancelEventHandler(textbox_DateTime_Validating); textbox_DateTime.TextChanged = new EventHandler(textbox_DateTime_TextChanged); } void textbox_DateTime_TextChanged(object sender, EventArgs e) { TextChanged_event(sender, e); } // void textbox_DateTime_Validating(object sender, CancelEventArgs e) { //如果控件不可交互,则不用验证 if (textbox_DateTime.Enabled == false) { return; } if (a_Check == true) { //这里还有一个错误,如果输入内容不对,点击那个BUTTON显示日期时,还是显示不到 if (g_month.Focused == false && string.IsNullOrEmpty(textbox_DateTime.Text) == false) { DateTime dt; if (!DateTime.TryParse(textbox_DateTime.Text, out dt)) { //PUB.pub_s_Message.fun_message("ucl-0003", 1, 5); //日期格式不对 e.Cancel = true; textbox_DateTime.SelectAll(); } } } } //光标离开 month 时,移除 month void month_Leave(object sender, EventArgs e) { Control l_control = g_month; while (l_control.Parent != null) { l_control = l_control.Parent; if (l_control.Controls.Contains(g_month)) { l_control.Controls.Remove(g_month); return; } } } //在 month 中选择日期后,移除month并给textbox赋值 void month_DateSelected(object sender, DateRangeEventArgs e) { textbox_DateTime.Text = e.Start.ToString(datetime_formate); textbox_DateTime.Focus(); Control l_control = g_month; while (l_control.Parent != null) { l_control = l_control.Parent; if (l_control.Controls.Contains(g_month)) { l_control.Controls.Remove(g_month); return; } } } //弹出日期控件 void customButton1_Click(object sender, EventArgs e) { if (textbox_DateTime.Enabled == false) { return; } if (this.Parent.Parent != null) { if (this.Parent.Parent.GetType().ToString() == "System.Windows.Forms.DataGridView") { DataGridView l_dtgv = (DataGridView)this.Parent.Parent; int l_x = l_dtgv.Location.X this.Parent.Location.X; int l_y = l_dtgv.Location.Y this.Parent.Location.Y textbox_DateTime.Height; //当行在右侧时,父控件右方空间不足以显示日期控件,则在父控件左方显示 if (l_dtgv.Width - this.Parent.Location.X < g_month.Width) { l_x = l_dtgv.Location.X this.Parent.Location.X - g_month.Width; } //当行在底部时,父控件的下方空间不足并且上方空间充足的情况下在父控件上方显示日期控件,则在BUTTON的上方显示 if (l_dtgv.Height - this.Parent.Location.Y < g_month.Height && this.Parent.Location.Y > g_month.Height) { l_y = l_dtgv.Location.Y this.Parent.Location.Y - g_month.Height; } g_month.Location = new Point(l_x,l_y); l_dtgv.Parent.Controls.Add(g_month); } else { g_month.Location = new Point(this.Parent.Location.X this.Location.X, this.Parent.Location.Y this.Location.Y textbox_DateTime.Height); this.Parent.Parent.Controls.Add(g_month); } } else { g_month.Location = new Point(this.Location.X, this.Location.Y textbox_DateTime.Height); this.Parent.Controls.Add(g_month); } g_month.BringToFront(); g_month.MaxSelectionCount = 1; g_month.Focus(); if (string.IsNullOrEmpty(textbox_DateTime.Text) == false) { try { g_month.SelectionStart = DateTime.Parse(textbox_DateTime.Text); } catch { g_month.SelectionStart = DateTime.Now; } } else { g_month.SelectionStart = DateTime.Now; } g_month.SelectionEnd = g_month.SelectionStart; } } /// <summary> /// 为了不显示BUTTON的聚焦框,自定义一个BUTTON,因为ShowFocusCues属性是受保护的,所以需要重写这个BUTTON的ShowFocusCues /// </summary> class CustomButton : System.Windows.Forms.Button { private bool _DisplayFocusCues = true; protected override bool ShowFocusCues { get { return _DisplayFocusCues; } } /// <summary> /// 是否显示聚焦框,重写的属性 /// </summary> [DefaultValue("True"), Description("是否显示聚焦框,重写的属性"), Category("Appearance")] public bool DisplayFocusCues { get { return _DisplayFocusCues; } set { _DisplayFocusCues = value; } } } #region 以下为自定义列类型代码段 public class UCL_Datetime_Column : DataGridViewColumn { public UCL_Datetime_Column() : base(new UCL_Datetime_Cell()) { } public override DataGridViewCell CellTemplate { get { return base.CellTemplate; } set { // Ensure that the cell used for the template is a UCL_Datetime_Cell. if (value != null && !value.GetType().IsAssignableFrom(typeof(UCL_Datetime_Cell))) { throw new InvalidCastException("Must be a UCL_Datetime_Cell"); } base.CellTemplate = value; } } public override object Clone() { UCL_Datetime_Column col = (UCL_Datetime_Column)base.Clone(); return col; } } public class UCL_Datetime_Cell : DataGridViewTextBoxCell { public UCL_Datetime_Cell() : base() { // Use the short date format. this.Style.Format = "d"; } public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) { // Set the value of the editing control to the current cell value. base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); UCL_Datetime_EditingControl ctl = DataGridView.EditingControl as UCL_Datetime_EditingControl; if (this.Value != null) { ctl.a_Text = this.Value.ToString(); } else { ctl.a_Text = DateTime.Now.ToShortDateString(); } } public override Type EditType { get { // Return the type of the editing contol that UCL_Datetime_Cell uses. return typeof(UCL_Datetime_EditingControl); } } //public override Type ValueType //{ // get // { // // Return the type of the value that UCL_Datetime_Cell contains. // return typeof(DateTime); // } //} public override object DefaultNewRowValue { get { // Use the current date and time as the default value. return DateTime.Now; } } } class UCL_Datetime_EditingControl : UCL_Datetime, IDataGridViewEditingControl { DataGridView dataGridView; private bool valueChanged = false; int rowIndex; public UCL_Datetime_EditingControl() { this.a_Formate = "yyyy-MM-dd"; this.TextChanged_event = new Text_Changed(UCL_Datetime_EditingControl_TextChanged_event); } void UCL_Datetime_EditingControl_TextChanged_event(object sender, EventArgs e) { valueChanged = true; this.EditingControlDataGridView.NotifyCurrentCellDirty(true); //this.EditingControlFormattedValue = this.a_Text; //base.OnDateChanged(sender, e); //base.OnTextChanged_event(sender, e); } // Implements the IDataGridViewEditingControl.EditingControlFormattedValue // property. public object EditingControlFormattedValue { get { return this.a_Text; } set { String newValue = value as String; if (newValue != null) { this.a_Text = DateTime.Parse(newValue).ToShortDateString(); } } } // Implements the // IDataGridViewEditingControl.GetEditingControlFormattedValue method. public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context) { return EditingControlFormattedValue; } // Implements the // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method. public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle) { this.Font = dataGridViewCellStyle.Font; this.ForeColor = dataGridViewCellStyle.ForeColor; this.BackColor = dataGridViewCellStyle.BackColor; } // Implements the IDataGridViewEditingControl.EditingControlRowIndex // property. public int EditingControlRowIndex { get { return rowIndex; } set { rowIndex = value; } } // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey // method. public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey) { // Let the DateTimePicker handle the keys listed. switch (key & Keys.KeyCode) { case Keys.Left: case Keys.Up: case Keys.Down: case Keys.Right: case Keys.Home: case Keys.End: case Keys.PageDown: case Keys.PageUp: return true; default: return false; } } // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit // method. public void PrepareEditingControlForEdit(bool selectAll) { // No preparation needs to be done. } // Implements the IDataGridViewEditingControl // .RepositionEditingControlOnValueChange property. public bool RepositionEditingControlOnValueChange { get { return false; } } // Implements the IDataGridViewEditingControl // .EditingControlDataGridView property. public DataGridView EditingControlDataGridView { get { return dataGridView; } set { dataGridView = value; } } // Implements the IDataGridViewEditingControl // .EditingControlValueChanged property. public bool EditingControlValueChanged { get { return valueChanged; } set { valueChanged = value; } } // Implements the IDataGridViewEditingControl // .EditingPanelCursor property. public Cursor EditingPanelCursor { get { return base.Cursor; } } //protected override void OnTextChanged_event(object sender, EventArgs eventargs) //{ // // Notify the DataGridView that the contents of the cell // // have changed. // valueChanged = true; // this.EditingControlDataGridView.NotifyCurrentCellDirty(true); // //this.OnDateChanged(sender,eventargs); // //this.OnTextChanged_event(sender, eventargs); // //base.OnTextChanged_event(sender, eventargs); // this.OnTextChanged_event(sender, eventargs); //} #endregion }}
评论