简体   繁体   中英

How do I prevent my ContextMenu from being constrained to its container (Win Forms c#)

I wrote a custom Control (an auto-complete TextBox (below)) in which a ContextMenuStrip is programmatically added to the form.

My problem is that when the control generates a list longer than the height of it's parent container ( Panel , GroupBox , etc) the bottom section of ContextMenuStrip is hidden.

I have tried calling .BringToFront() but can't find any way to overcome this behaviour.

Any help would be greatly appriciated, also feel free to steal the control :)

fig 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();
                }
            }
        }
    }

}

It's because you turned it into a child control by setting its TopLevel property to false and adding it to the parent's Control collection. Replace this:

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

with this:

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

Beware that the CMS will overlap the text box if it is too tall.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM