2016-09-22 21 views
0

さまざまなコントロールとラベルを含むTableLayoutPanelを含むフォームがあります。そのうちの1つはComboBoxから継承したカスタムコントロールで、余分な自動補完動作をしています(左から右のテキストではなく自動補完します)。私はこのコントロールのコードを書いていないので、どのように動作するのかよく知っているわけではありませんが、基本的にはComboboxをクリックすると、ComboBoxの下のListBoxがTableLayoutPanelの同じPanel内に追加されます。通常のドロップダウン。ListBoxでTableLayoutPanelをオーバーラップさせる(C#.NET)

残念ながら、TableLayoutPanelはListBoxが追加されたときに完全に表示されないようにし、1つの項目だけが表示されるようにします。目標は、通常のComboBoxのように見えるようにすることです。通常のComboBoxは、その下のコントロールをカバーするようにドロップされます。

TableLayoutPanelにあるコントロールを許可して、TableLayoutPanelをオーバーラップさせて、これを必要に応じて動作させる方法はありますか?私はListBoxを収容するために成長しているTableLayoutPanelのために動き回るコントロールを避けたい。コントロールから

関連するコード:

void InitListControl() 
     { 
      if (listBoxChild == null) 
      { 
       // Find parent - or keep going up until you find the parent form 
       ComboParentForm = this.Parent; 

       if (ComboParentForm != null) 
       { 
        // Setup a messaage filter so we can listen to the keyboard 
        if (!MsgFilterActive) 
        { 
         Application.AddMessageFilter(this); 
         MsgFilterActive = true; 
        } 

        listBoxChild = listBoxChild = new ListBox(); 
        listBoxChild.Visible = false; 
        listBoxChild.Click += listBox1_Click; 
        ComboParentForm.Controls.Add(listBoxChild); 
        ComboParentForm.Controls.SetChildIndex(listBoxChild, 0); // Put it at the front 
       } 
      } 
     } 


     void ComboListMatcher_TextChanged(object sender, EventArgs e) 
     { 
      if (IgnoreTextChange > 0) 
      { 
       IgnoreTextChange = 0; 
       return; 
      } 

      InitListControl(); 

      if (listBoxChild == null) 
       return; 

      string SearchText = this.Text; 

      listBoxChild.Items.Clear(); 

      // Don't show the list when nothing has been typed 
      if (!string.IsNullOrEmpty(SearchText)) 
      { 
       foreach (string Item in this.Items) 
       { 
        if (Item != null && Item.ToLower().Contains(SearchText.ToLower())) 
        { 
         listBoxChild.Items.Add(Item); 
         listBoxChild.SelectedIndex = 0; 
        } 
       } 
      } 

      if (listBoxChild.Items.Count > 0) 
      { 
       Point PutItHere = new Point(this.Left, this.Bottom); 
       Control TheControlToMove = this; 

       PutItHere = this.Parent.PointToScreen(PutItHere); 

       TheControlToMove = listBoxChild; 
       PutItHere = ComboParentForm.PointToClient(PutItHere); 

       TheControlToMove.Anchor = ((System.Windows.Forms.AnchorStyles) 
        ((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); 
       TheControlToMove.BringToFront(); 
       TheControlToMove.Show(); 
       TheControlToMove.Left = PutItHere.X; 
       TheControlToMove.Top = PutItHere.Y; 
       TheControlToMove.Width = this.Width; 

       int TotalItemHeight = listBoxChild.ItemHeight * (listBoxChild.Items.Count + 1); 
       TheControlToMove.Height = Math.Min(ComboParentForm.ClientSize.Height - TheControlToMove.Top, TotalItemHeight); 
      } 
      else 
       HideTheList(); 
     } 

画像:TAWからの提案に行く

Desired behavior

Current behavior

+0

子供はその容器を重ねることはできません。 [この投稿を見る](http://stackoverflow.com/questions/39637490/winforms-splitterpanel-z-index-of-child-overlap-split/39649087#39649087)が必要な場合があります。または、コンボボックスを使用します。ドロップダウンは実際には子コントロールではありませんが、オーバーレイされて表示されるので、フォームの枠線と重なることさえあります。 – TaW

+0

私は必要な余分な自動補完機能がないため、ComboBoxを使用できません。子コントロールがコンテナと重ならないことについてあなたが言うことに興味があります。理にかなっていますが、私はそれがすべての場合に当てはまるかどうかはわかりませんでした。ドロップダウンがコンテナに重なる可能性がある場合、カスタムコントロールでその動作を模倣する方法はないはずです。 – user2961731

+0

Dropdownsを一時的なウィンドウ/フォームと考えてください!はい、それもオプションです。もしあなたが手頃なものを見つけることができない場合は、コンボックスの自動完成版を作成することができます。 – TaW

答えて

0

、私は暫定的な解決策を考え出しました。このフォームはサイズ変更することはできませんが、WindowsでDPIを変更した場合は自動サイズになります。

これを解決するため、TableLayoutPanelのコントロールをTableLayoutPanelのParentの任意の位置に移動しました。フォームのロード時に、私はTableLayoutPanelの座標と、コントロールの上に配置したいセルの空のパネルを合計しました。これは私のニーズにも役立ちましたが、クルーグのように感じます。

もっと良い解決策は、おそらくControl.PointToScreenメソッドとControl.PointToClientメソッドを使用することですが、これらのメソッドを使用して正しい座標を与えることができませんでした。

関連する問題