2010-04-26 41 views
0

我编写了自定义的Control(自动完成TextBox(下)),其中ContextMenuStrip以编程方式添加到表单中。如何防止我的ContextMenu受限于其容器(Win Forms c#)

我的问题是,当控件生成的列表长度超过其父容器的高度时(Panel,GroupBox等),ContextMenuStrip的底部部分被隐藏。

我曾尝试致电.BringToFront(),但无法找到任何方法来解决此问题。

任何帮助将大大appriciated,还随意窃取控制:)

图1.

/// <summary> 
/// TextBox which can auto complete words found in a table column 
/// Just set DataSource and DataListField and start typing - WD 
/// </summary> 
public class AutoComplete : TextBox 
{ 
    public DataTable DataSource { get; set; } 
    public string DataListField { get; set; } 
    private ContextMenuStrip SuggestionList = new ContextMenuStrip(); 

    public AutoComplete() 
    { 
     this.LostFocus += new EventHandler(AutoComplete_LostFocus); 
     KeyUp += new KeyEventHandler(AutoComplete_KeyUp); 
     SuggestionList.ItemClicked += new ToolStripItemClickedEventHandler(SuggestionList_ItemClicked); 
    } 

    void AutoComplete_LostFocus(object sender, EventArgs e) 
    { 
     if (!SuggestionList.Focused) 
     { 
      SuggestionList.Visible = false; 
     } 
    } 

    void SuggestionList_ItemClicked(object sender, ToolStripItemClickedEventArgs e) 
    { 
     this.Text = e.ClickedItem.Text; 
     SuggestionList.Visible = false; 
     this.Focus(); 
     SuggestionList.Visible = false; 
    } 

    void AutoComplete_KeyUp(object sender, KeyEventArgs e) 
    { 
     if (null != DataSource && DataSource.Rows.Count > 0 && null != DataListField) 
     { 
      if (e.KeyCode != Keys.Enter) 
      { 
       if (SuggestionList.Items.Count > 0 && e.KeyCode == Keys.Down) 
       { 
        SuggestionList.Focus(); 
        SuggestionList.Items[0].Select(); 
        SuggestionList.BringToFront(); 
       } 
       else if (this.Text.Length > 0) 
       { 
        SuggestionList.Items.Clear(); 

        DataRow[] drSuggestionList = DataSource.Select("[" + DataListField + "] LIKE '" + this.Text + "%'"); 

        foreach (DataRow dr in drSuggestionList) 
        { 
         SuggestionList.Items.Add(dr[DataListField].ToString()); 
        } 

        SuggestionList.TopLevel = false; 
        SuggestionList.Visible = true; 
        SuggestionList.Top = (this.Top + this.Height); 
        SuggestionList.Left = this.Left; 
        this.Parent.Controls.Add(SuggestionList); 
        SuggestionList.BringToFront(); 
       } 
      } 
     } 
    } 

} 

回答

1

这是因为你把它变成一个子控件通过它的顶层属性设置为false并将其添加到父级的Control集合中。替换此:

   SuggestionList.TopLevel = false; 
       SuggestionList.Visible = true; 
       SuggestionList.Top = (this.Top + this.Height); 
       SuggestionList.Left = this.Left; 
       this.Parent.Controls.Add(SuggestionList); 
       SuggestionList.BringToFront(); 

与此:

 SuggestionList.Show(this.Parent.PointToScreen(new Point(this.Left, this.Bottom))); 

当心CMS将重叠的文本框中,如果它是太高。

+0

谢谢,这确实解决了我提出的问题,但它也介入了用户打字,我似乎无法使用this.Focus()后它将光标放回到文本框中:? – WillDud 2010-04-26 15:39:37

+1

你是对的,这是一个显示瓶塞问题。 CMS在失去焦点时会自动关闭。您知道TextBox已经提供了AutoCompleteSource属性? – 2010-04-26 15:58:14

+0

是的,这是我的workaroud允许通配符如*和%和一点练习锻炼,欢呼的帮助:) – WillDud 2010-04-27 16:12:28