自定義彈出控件(上)

来源:互联网 发布:开淘宝店电脑配置要求 编辑:程序博客网 时间:2024/05/15 23:45

自定義彈出控件(上)


原理:
用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(0this.Height);

            
if ((this.PointToScreen(new Point(00)).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(thisthis.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(thisthis.CalculatePoz());
                }
                
return;
            }
            
#endregion

            
base.WndProc(ref m);
        }
    }

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

原创粉丝点击