2010-04-26 4 views
0

J'ai écrit un Control personnalisé (un auto-complet TextBox (ci-dessous)) dans lequel un ContextMenuStrip est ajouté par programmation au formulaire.Comment empêcher mon ContextMenu d'être contraint à son conteneur (Win Forms C#)

Mon problème est que lorsque le contrôle génère une liste plus longue que la hauteur de son conteneur parent (Panel, GroupBox, etc.) la section inférieure de ContextMenuStrip est masquée.

J'ai essayé d'appeler .BringToFront() mais je ne trouve aucun moyen de résoudre ce problème.

Toute aide serait grandement appriciated, aussi se sentir libre de voler le contrôle :)

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

} 

Répondre

1

C'est parce que vous l'a transformé en un contrôle enfant en définissant sa propriété TopLevel false et en l'ajoutant à la collection Control du parent. Remplacer ceci:

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

avec ceci:

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

que le CMS Beware se chevauchent la zone de texte si elle est trop grand.

+0

Merci, cela résout le problème que j'ai soulevé, mais il intercepte aussi les utilisateurs qui tapent et je n'arrive pas à l'utiliser.Focus() après le retour du curseur dans la zone de texte:? – WillDud

+1

Vous avez raison, c'est un problème de spectacle. Le CMS se ferme automatiquement lorsqu'il perd le focus. Vous êtes conscient que TextBox fournit déjà la propriété AutoCompleteSource? –

+0

Oui, ceci est mon workaroud pour permettre des caractères génériques comme * et% et un peu d'exercice d'exercice, applaudissements pour l'aide :) – WillDud