可以为空值、可以删除显示日期的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
ExpandedBlockStart.gifContractedBlock.gif
{
    [ToolboxBitmap(
typeof(System.Windows.Forms.DateTimePicker))]
    
public class FlatDateTimePicker: DateTimePicker
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
ContractedSubBlock.gifExpandedSubBlockStart.gif        
ComboInfoHelper#region ComboInfoHelper
        
internal class ComboInfoHelper
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            [DllImport(
"user32")]
            
private static extern bool GetComboBoxInfo(IntPtr hwndCombo, ref ComboBoxInfo info);

ContractedSubBlock.gifExpandedSubBlockStart.gif            
RECT struct#region RECT struct
            [StructLayout(LayoutKind.Sequential)]
            
private struct RECT
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
public int Left;
                
public int Top;
                
public int Right;
                
public int Bottom;
            }

            
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif            
ComboBoxInfo Struct#region ComboBoxInfo Struct
            [StructLayout(LayoutKind.Sequential)]
            
private struct ComboBoxInfo
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
public int cbSize;
                
public RECT rcItem;
                
public RECT rcButton;
                
public IntPtr stateButton;
                
public IntPtr hwndCombo;
                
public IntPtr hwndEdit;
                
public IntPtr hwndList;
            }

            
#endregion


            
public static int GetComboDropDownWidth()
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ComboBox cb 
= new ComboBox();
                
//DateTimePicker cb = new DateTimePicker();
                int width = GetComboDropDownWidth(cb.Handle);
                cb.Dispose();
                
return width;
            }

            
public static int GetComboDropDownWidth(IntPtr handle)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ComboBoxInfo cbi 
= new ComboBoxInfo();
                cbi.cbSize 
= Marshal.SizeOf(cbi);
                GetComboBoxInfo(handle, 
ref cbi);
                
int width = cbi.rcButton.Right - cbi.rcButton.Left;
                
return width;
            }

        }

        
#endregion


        [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 Pen BorderPen  = new Pen(Color.Black, 2);
        
private Pen BorderPenControl  = new Pen(SystemColors.ControlDark, 2);
        
private bool DroppedDown = false;
        
private int InvalidateSince = 0;
        
private static int DropDownButtonWidth = 17;

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


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

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


        
protected override void WndProc(ref Message m)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
//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)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
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 PaintFlatDropDown(Control ctrl, Graphics g)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            Rectangle rect 
= new Rectangle(ctrl.Width - DropDownButtonWidth, 0, DropDownButtonWidth, ctrl.Height);
            ControlPaint.DrawComboButton(g, rect, ButtonState.Flat);
        }

        
private void SendPrintClientMsg()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
// 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)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (text != "")
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
this.Format = DateTimePickerFormat.Long;

                
this.Text = text;
            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
this.Format = DateTimePickerFormat.Custom;
            }

        }

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

        }


        
private void OverrideControlBorder(Graphics g)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
//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)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
this.Format = DateTimePickerFormat.Custom;
                
this.CustomFormat = " ";
                
// OnValueChanged(EventArgs.Empty);
            }

            
base.OnKeyUp(e);
        }

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

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

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


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


    }

}

 

转载于:https://www.cnblogs.com/ttinfo/archive/2006/11/30/578149.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值