自定義彈出控件(上)

自定義彈出控件(上)


原理:
用ToolStripDropDown做為自定義控件的容器,在使用時只需調用相應事件彈出這個容器就可以了.
自定義控件必須從ToolStripControlHost類派生,並用我們需要的一個控件進行初始化(這個控件可以是標準控件,也可以是用戶控件).
製作步驟:
1.定義好一個我們需要的控件或直接選擇一個標準控件.
2.定義一個ToolStripControlHost派生類,並用先前定義的那個控件初始化.
3.使用ToolStripDropDown作為容器,將ToolStripControlHost派生類裝入,在需要的地方按設定容器的大小並彈出這個容器.
以下以製作一個DateTimeComboBox為例
1.我們打算直接彈出一個MonthCalendar控件,所以這一步就不用做.
2.定義ToolStripMonthCalendar,它繼承自ToolStripControlHost,並用一個MonthCalendar實例初始化,在這裡可以暴露MonthCalendar的一部分屬性和方法. 

public   class  ToolStripMonthCalendar : ToolStripControlHost
    {
        
//  Call the base constructor passing in a MonthCalendar instance.
        
// 用MonthCalendar初始化
         public  ToolStripMonthCalendar() :  base ( new  MonthCalendar()) { }

        
public  MonthCalendar MonthCalendarControl
        {
            
get
            {
                
return  Control  as  MonthCalendar;
            }
        }

        
//  Expose the MonthCalendar.FirstDayOfWeek as a property.
        
// 暴露FirstDayOfWeek屬性
         public  Day FirstDayOfWeek
        {
            
get
            {
                
return  MonthCalendarControl.FirstDayOfWeek;
            }
            
set
            {
                value 
=  MonthCalendarControl.FirstDayOfWeek;
            }
        }

        
//  Expose the AddBoldedDate method.
        
// 暴露AddBoldedDate方法
         public   void  AddBoldedDate(DateTime dateToBold)
        {
            MonthCalendarControl.AddBoldedDate(dateToBold);
        }

        
//  Subscribe and unsubscribe the control events you wish to expose.
        
// 覆寫顯示下拉控件時調用的函數
         protected   override   void  OnSubscribeControlEvents(Control c)
        {
            
base .OnSubscribeControlEvents(c);

            
//  Cast the control to a MonthCalendar control.
            MonthCalendar monthCalendarControl  =  (MonthCalendar)c;

            
//  Add the event.
            monthCalendarControl.DateChanged  +=   new  DateRangeEventHandler(OnDateChanged);
        }
        
// 覆寫隱藏下拉控件時調用的函數
         protected   override   void  OnUnsubscribeControlEvents(Control c)
        {
            
base .OnUnsubscribeControlEvents(c);

            
//  Cast the control to a MonthCalendar control.
            MonthCalendar monthCalendarControl  =  (MonthCalendar)c;

            
//  Remove the event.
            monthCalendarControl.DateChanged  -=   new  DateRangeEventHandler(OnDateChanged);
        }

        
//  Declare the DateChanged event.
        
// 聲明日期變更事件
         public   event  DateRangeEventHandler DateChanged;

        
//  Raise the DateChanged event.
         private   void  OnDateChanged( object  sender, DateRangeEventArgs e)
        {
            
if  (DateChanged  !=   null )
            {
                DateChanged(
this , e);
            }
        }
    }

3.在指定位置彈出容器. 

public   partial   class  DateTimeComboBox : ComboBox
    {
        
private   const  UInt32 WM_LBUTTONDOWN  =   0x201 ;
        
private   const  UInt32 WM_LBUTTONDBLCLK  =   0x203 ;
        
private   const  UInt32 WM_KEYF4  =   0x134 ;
        
private   const  UInt32 WM_CTLCOLORLISTBOX  =   0x0134 ;
        ToolStripMonthCalendar myTSMonthCalendar;
        ToolStripDropDown tsDD;

        
public  DateTimeComboBox()
        {
            InitializeComponent();
            myTSMonthCalendar 
=   new  ToolStripMonthCalendar();
            tsDD 
=   new  ToolStripDropDown();

            
//  事件調用,如果在彈出控件時並不想改變控件的屬性,這步可省略.
             this .myTSMonthCalendar.MonthCalendarControl.DateChanged  +=   new  System.Windows.Forms.DateRangeEventHandler( this .myTSMonthCalendar_DateChanged);
            
this .myTSMonthCalendar.MonthCalendarControl.KeyDown  +=   new  System.Windows.Forms.KeyEventHandler( this .myTSMonthCalendar_KeyDown);
        }

        
#region  事件
        
private   void  myTSMonthCalendar_DateChanged( object  sender, DateRangeEventArgs e)
        {
            
this .Text  =  e.End.ToShortDateString();
        }
        
private   void  myTSMonthCalendar_KeyDown( object  sender, KeyEventArgs e)
        {
            
if  (e.KeyCode  ==  Keys.Enter)
                
this .tsDD.Close();

        }
        
#endregion

        
#region  方法,計算容器在彈出時的左上角坐標

 
// 這個函數有個點問題,它沒有考慮到彈出容器超出屏幕的情況.
         private  Point CalculatePoz()
        {
            Point point 
=   new  Point( 0 this .Height);

            
if  (( this .PointToScreen( new  Point( 0 0 )).Y  +   this .Height  +   this .myTSMonthCalendar.Height)  >  Screen.PrimaryScreen.WorkingArea.Height)
            {
                point.Y 
=   - this .myTSMonthCalendar.Height  -   7 ;
            }

            
return  point;
        }
        
#endregion

        
protected   override   void  WndProc( ref  Message m)
        {
            
#region  WM_KEYF4
            
if  (m.Msg  ==  WM_KEYF4)
            {
                
this .Focus();
                
this .tsDD.Refresh();
                
if  ( ! this .tsDD.Visible)
                {
                    
try
                    {
                        
if  ( this .Text  !=   "" )
                            
this .myTSMonthCalendar.MonthCalendarControl.SetDate(Convert.ToDateTime( this .Text));
                    }
                    
catch  (Exception)
                    {
                        MessageBox.Show(
" Data nu este in formatul corect! " );
                    }
       
// 在彈出容器中添加項目
                    tsDD.Items.Add( this .myTSMonthCalendar);
                    
// 彈出容器
                    tsDD.Show( this this .CalculatePoz());
                }

                
return ;
            }
            
#endregion

            
#region  WM_LBUTTONDBLCLK
            
if  (m.Msg  ==  WM_LBUTTONDBLCLK  ||  m.Msg  ==  WM_LBUTTONDOWN)
            {
                
if  ( ! this .tsDD.Visible)
                {
                    
try
                    {
                        
if  ( this .Text  !=   "" )
                            
this .myTSMonthCalendar.MonthCalendarControl.SetDate(Convert.ToDateTime( this .Text));
                    }
                    
catch  (Exception)
                    {
                        MessageBox.Show(
" Data nu este in formatul corect! " );
                    }
                    
// 在彈出容器中添加項目
                    tsDD.Items.Add( this .myTSMonthCalendar);
                    
// 彈出容器
                    tsDD.Show( this this .CalculatePoz());
                }
                
return ;
            }
            
#endregion

            
base .WndProc( ref  m);
        }
    }

參考文獻:1.http://hi.baidu.com/pzy84/blog/item/22f4ef77bfd94619b151b92c.html
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值