网站首页 免费电影 3gp手机电 美发视频 发型图片 美发学校 美发沙龙 美发茶座 产品器材 二手市场 求职招聘 美发圈子 美发问答 论坛首页
发新话题
打印

让DateTimePicker显示空时间值

让DateTimePicker显示空时间值

写在前面:在.net中让DateTimePicker显示一个空的时间值,也许是很容易的事情,但事实上,也不是很容易的,至少,没有经过努力的修改和重画,你是达不到的。在修改这个控件的时候,你又常常发现会有bug。下面介绍一个方法,至少源作者是经过研究的,没有发现多少问题。

源网址
http://www.codeproject.com/KB/selection/Nullable_DateTimePicker.aspx
你可以在上述的网址找到源代码和英文的说明。

效果图
下图中,你只要按一下Delete键就可以将DateTimePicker的值设置为空,实际的值是DateTime.MinValue,这一个简单的效果,也许是很多程序员想看到。不过学习一下这个控件。
 

源代码
最重要的两个重载方法是下面俩。
protected override void OnCloseUp(EventArgs eventargs)
protected override void OnKeyDown(KeyEventArgs e)
DateTimePicker本身是支持自定义格式的,DateTimePickerFormat.Custom,就是声明使用自定义格式的。
  public new DateTime Value
  {
   get
   {
    if (bIsNull)
     return DateTime.MinValue;
    else
     return base.Value;
   }
   set
   {
    if (value == DateTime.MinValue)
    {
     if (bIsNull == false)
     {
      oldFormat = this.Format;
      oldCustomFormat = this.CustomFormat;
      bIsNull = true;
     }

     this.Format = DateTimePickerFormat.Custom;
     this.CustomFormat = " ";
    }
    else
    {
     if (bIsNull)
     {
      this.Format = oldFormat;
      this.CustomFormat = oldCustomFormat;
      bIsNull = false;
     }
     base.Value = value;
    }
   }
  }


TOP

可以为空值、可以删除显示日期的DateTimePicker

  .Net的DateTimePicker没有提供空白显示的功能,一旦选择了日期,也不可删除而显示空白,且在非Windows XP主体环境下也没有Flat显示功能,直接放在界面上还真不太美观,于是着手改造了一下。
     如果想出时显示时日期为空,则设置Format属性为Custom,设置CustomFormat属性为空格" "即可:
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using Srims.UI.Controls;
namespace DrawFlat
{
    [ToolboxBitmap(
typeof(System.Windows.Forms.DateTimePicker))]
    
public class FlatDateTimePicker: DateTimePicker
    
{
        
ComboInfoHelper

        [DllImport(
"user32.dll", EntryPoint="SendMessageA")]
        
private static extern int SendMessage (IntPtr hwnd, int wMsg, IntPtr wParam, int lParam);

        [DllImport(
"user32")]
        
private static extern IntPtr GetWindowDC (IntPtr hWnd );

        [DllImport(
"user32")]
        
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC );

        
const int WM_ERASEBKGND = 0x14;
        
const int WM_PAINT = 0xF;
        
const int WM_NC_HITTEST = 0x84;
        
const int WM_NC_PAINT = 0x85;
        
const int WM_PRINTCLIENT = 0x318;
        
const int WM_SETCURSOR = 0x20;


        
private en BorderPen  = new en(Color.Black, 2);
        
private en BorderPenControl  = new en(SystemColors.ControlDark, 2);
        
private bool DroppedDown = false;
        
private int InvalidateSince = 0;
        
private static int DropDownButtonWidth = 17;

        
static FlatDateTimePicker()
        
{
            
// 2 pixel extra is for the 3D border around the pulldown button on the left and right
            DropDownButtonWidth = ComboInfoHelper.GetComboDropDownWidth()+2 ;    
        }


        
public FlatDateTimePicker()
            : 
base()
        
{
            
this.SetStyle(ControlStyles.DoubleBuffer, true);
            
//this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        }

        
protected override void OnValueChanged(EventArgs eventargs)
        
{
            
base.OnValueChanged (eventargs);
            
this.Invalidate();
        }


        
protected override void WndProc(ref Message m)
        
{
            
//IntPtr hDC = IntPtr.Zero;
            
//Graphics gdc = null;
            
//switch (m.Msg)
            
//{
            
//    case WM_NC_PAINT:
            
//        hDC = GetWindowDC(m.HWnd);
            
//        gdc = Graphics.FromHdc(hDC);
            
//        SendMessage(this.Handle, WM_ERASEBKGND, hDC, 0);
            
//        SendPrintClientMsg();
            
//        SendMessage(this.Handle, WM_PAINT, IntPtr.Zero, 0);
            
//        OverrideControlBorder(gdc);
            
//        //PaintFlatControlBorder(this, gdc);
            
//        m.Result = (IntPtr)1;    // indicate msg has been processed
            
//        ReleaseDC(m.HWnd, hDC);
            
//        gdc.Dispose();
            
//        break;
            
//    case WM_PAINT:
            
//        base.WndProc(ref m);
            
//        hDC = GetWindowDC(m.HWnd);
            
//        gdc = Graphics.FromHdc(hDC);
            
//        OverrideDropDown(gdc);
            
//        OverrideControlBorder(gdc);
            
//        //PaintFlatControlBorder(this, gdc);
            
//        ReleaseDC(m.HWnd, hDC);
            
//        gdc.Dispose();
            
//        break;
            
//    /*
            
//    // We don't need this anymore, handle by WM_SETCURSOR
            
//    case WM_NC_HITTEST: 
            
//        base.WndProc(ref m);
            
//        if (DroppedDown)
            
//        {
            
//            OverrideDropDown(gdc);
            
//            OverrideControlBorder(gdc);
            
//        }
            
//        break;
            
//    */
            
//    //case WM_SETCURSOR:
            
//    //    base.WndProc(ref m);
            
//    //    // The value 3 is discovered by trial on error, and cover all kinds of scenarios
            
//    //    // InvalidateSince < 2 wil have problem if the control is not in focus and dropdown is clicked
            
//    //    if (DroppedDown && InvalidateSince < 3)
            
//    //    {
            
//    //        Invalidate();
            
//    //        InvalidateSince++;
            
//    //    }
            
//    //    break;
            
//    default:
            
//        base.WndProc(ref m);
            
//        break;
            
//}
            IntPtr hDC = GetWindowDC(m.HWnd);
            Graphics gdc 
= Graphics.FromHdc(hDC);
            
switch (m.Msg)
            
{
                
case WM_NC_PAINT:
                    SendMessage(
this.Handle, WM_ERASEBKGND, hDC, 0);
                    SendPrintClientMsg();
                    SendMessage(
this.Handle, WM_PAINT, IntPtr.Zero, 0);
                    OverrideControlBorder(gdc);

                    m.Result 
= (IntPtr)1// indicate msg has been processed
                    break;
                
case WM_PAINT: base.WndProc(ref m);
                    OverrideControlBorder(gdc);
                    OverrideDropDown(gdc);
                    
break;
                
case WM_NC_HITTEST:
                    
base.WndProc(ref m);
                    
if (DroppedDown)
                        
this.Invalidate(this.ClientRectangle, false);
                    
break;
                
default:
                    
base.WndProc(ref m);
                    
break;
            }

            ReleaseDC(m.HWnd, hDC);
            gdc.Dispose();    

            
        }

        
public static void aintFlatDropDown(Control ctrl, Graphics g)
        
{
            Rectangle rect 
= new Rectangle(ctrl.Width - DropDownButtonWidth, 0, DropDownButtonWidth, ctrl.Height);
            ControlPaint.DrawComboButton(g, rect, ButtonState.Flat);
        }

        
private void SendPrintClientMsg()
        
{
            
// We send this message for the control to redraw the client area
            Graphics gClient = this.CreateGraphics();
            IntPtr ptrClientDC 
= gClient.GetHdc();
            SendMessage(
this.Handle, WM_PRINTCLIENT, ptrClientDC, 0);
            gClient.ReleaseHdc(ptrClientDC);
            gClient.Dispose();
        }

        
public void SetText(string text)
        
{
            
if (text != "")
            
{
                
this.Format = DateTimePickerFormat.Long;

                
this.Text = text;
            }

            
else
            
{
                
this.Format = DateTimePickerFormat.Custom;
            }

        }

        
private void OverrideDropDown(Graphics g)
        
{
            
if (!this.ShowUpDown)
            
{
                Rectangle rect 
= new Rectangle(this.Width-DropDownButtonWidth, 0, DropDownButtonWidth, this.Height);
                ControlPaint.DrawComboButton(g, rect, ButtonState.Flat);    
            }

        }


        
private void OverrideControlBorder(Graphics g)
        
{
            
//this.Width = this.Width + 4;

            
if (this.Focused == false || this.Enabled == false )
                g.DrawRectangle(BorderPenControl, 
new Rectangle(00this.Width, this.Height));
            
else
                g.DrawRectangle(BorderPen, 
new Rectangle(00this.Width, this.Height));
        }

        
protected override void OnKeyUp(KeyEventArgs e)
        
{
            
if (e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete)
            
{
                
this.Format = DateTimePickerFormat.Custom;
                
this.CustomFormat = " ";
                
// OnValueChanged(EventArgs.Empty);
            }

            
base.OnKeyUp(e);
        }

        
protected override void OnDropDown(EventArgs eventargs)
        
{
            InvalidateSince 
= 0;
            DroppedDown 
= true;
            
base.OnDropDown (eventargs);
        }

        
protected override void OnCloseUp(EventArgs eventargs)
        
{
            DroppedDown 
= false;
            
this.Format = DateTimePickerFormat.Long;
            
base.OnCloseUp (eventargs);
        }

    
        
protected override void OnLostFocus(System.EventArgs e)
        
{
            
base.OnLostFocus(e);
            
this.Invalidate();
        }


        
protected override void OnGotFocus(System.EventArgs e)
        
{
            
base.OnGotFocus(e);
            
this.Invalidate();
        }
        
        
protected override void OnResize(EventArgs e)
        
{
            
base.OnResize (e);
            
this.Invalidate();
        }


    }

}

TOP

发新话题