2013-05-13 4 views
0

ContainerControl에서 상속하는 사용자 지정 ComboBox를 만들려고합니다. this 문서를 기본으로 사용했지만 다시 작성했지만 ToolStripControlHost, 내 사용자 지정 ListBox & ToolStripDropDown을 사용합니다.사용자 지정 ComboBox가 제대로 닫히지 않습니다.

이제 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을 표시합니다. 이 모든 것이 빠른 닫힘을 초래합니다.

저는이 문제에 잠깐 동안 고생했습니다. Google은이 주제에 대해 많이 알지 못합니다. (CodeProject의 기사에는 같은 버그가 있습니다.)

내가 시도한 것은 AutoClose를 사용하지 않고 DropDown을 표시 한 후 마우스를 캡처하는 것입니다. 이는 부분적으로 작동하지만 호스트 된 ListBox의 작동에 영향을 미칩니다. ListBox에는 컨트롤 집합 (항목)이 포함되어 있으며 이러한 항목에는 호버 페인트 효과가 있습니다. ListBox 컨트롤에서 마우스를 캡처하면 OnMouseEnter가 시작되지 않습니다.

모든 입력 사항을 매우 높이 평가할 것입니다.

답변

1

드롭 다운이 닫힐 때 커서 위치를 추적하려면 변수가 필요합니다.

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); 
    } 
} 
: 여기

빠른 더러운 예 제어부이며

관련 문제