2013-05-13 28 views
0

我想讓我的自定義組合框繼承自ContainerControl。我用this文章作爲基礎,但重寫了它,但我使用ToolStripControlHost,我自己的自定義ListBox &一個ToolStripDropDown。自定義組合框不能正常關閉

現在ComboBox是一個按鈕,您可以通過點擊來顯示包含我的ListBox的DropDown,並且可以覆蓋OnMouseClick。

的問題,開始時我嘗試關閉的下拉列表中,用下拉的「自動關閉」屬性設置爲true,則下拉如果你點擊下拉(包括按鈕)之外的某處關閉...

protected override void OnMouseClick(MouseEventArgs e) 
{ 
    base.OnMouseClick(e); 
     /* listboxControl = ToolStripDropDown */ 
    if (!listboxControl.Visible) 
    { 
    listboxControl.Show(this, GetDropLocation(), ToolStripDropDownDirection.BelowRight); 
      //listbox.Capture = true; 
    } 
} 

這是點擊按鈕的代碼..所以如果點擊它會發生什麼? 如果顯示DropDown,它首先關閉DropDown,然後觸發OnMouseClick事件。含義:listboxControl.Visible已經是假的&它會再次顯示DropDown。所有這些都導致了一個快速的公開。

我一直堅持這個問題一段時間了,谷歌似乎不知道這個問題很多(CodeProject上的那篇文章也有同樣的錯誤)。

我試過的是禁用AutoClose並在顯示DropDown後捕獲鼠標,這部分工作,但它影響我託管的ListBox的工作。 ListBox包含一組控件(項目),這些項目具有懸停繪畫效果。在ListBox控件中捕獲鼠標可以防止OnMouseEnter被觸發。

所有輸入將不勝感激!

回答

1

當DropDown關閉時,您需要一個變量來跟蹤光標位置。

這裏是一個快速和骯髒的示例性控制:

public class CustomDropBox : Control { 
    private ListBox box = new ListBox() { IntegralHeight = false }; 
    private ToolStripControlHost host; 
    private ToolStripDropDown drop; 
    private bool wasShowing = false; 

    public CustomDropBox() { 
    box.MinimumSize = new Size(120, 120); 
    box.MouseUp += box_MouseUp; 
    box.KeyPress += box_KeyPress; 
    box.Items.AddRange(new string[] { "aaa", "bbb", "ccc" }); 
    host = new ToolStripControlHost(box) { Padding = Padding.Empty }; 
    drop = new ToolStripDropDown() { Padding = Padding.Empty }; 
    drop.Closing += drop_Closing; 
    drop.Items.Add(host); 
    } 

    private Rectangle GetDownRectangle() { 
    return new Rectangle(this.ClientSize.Width - 16, 0, 16, this.ClientSize.Height); 
    } 

    void drop_Closing(object sender, ToolStripDropDownClosingEventArgs e) { 
    if (e.CloseReason == ToolStripDropDownCloseReason.AppClicked) { 
     wasShowing = GetDownRectangle().Contains(this.PointToClient(Cursor.Position)); 
    } else { 
     wasShowing = false; 
    } 
    } 

    void box_KeyPress(object sender, KeyPressEventArgs e) { 
    if (e.KeyChar == (char)Keys.Enter && box.SelectedIndex > -1) { 
     drop.Close(); 
    } 
    } 

    void box_MouseUp(object sender, MouseEventArgs e) { 
    int index = box.IndexFromPoint(e.Location); 
    if (index > -1) { 
     drop.Close(); 
    } 
    } 

    protected override void OnMouseDown(MouseEventArgs e) { 
    if (e.Button == MouseButtons.Left && GetDownRectangle().Contains(e.Location)) { 
     if (wasShowing) { 
     wasShowing = false; 
     } else { 
     drop.Show(this, new Point(0, this.Height)); 
     } 
    }  
    base.OnMouseDown(e); 
    } 

    protected override void OnPaint(PaintEventArgs e) { 
    e.Graphics.Clear(Color.White); 
    ControlPaint.DrawComboButton(e.Graphics, GetDownRectangle(), ButtonState.Normal); 
    base.OnPaint(e); 
    } 
}