簡體   English   中英

允許列表框與TableLayoutPanel(C#.NET)重疊

[英]Allow a ListBox to overlap a TableLayoutPanel (C# .NET)

我有一個包含TableLayoutPanel的表單,其中包含各種控件和標簽。 其中之一是從ComboBox繼承的自定義控件,該控件具有額外的自動完成行為(在任何文本上自動完成,而不是從左到右)。 我沒有為該控件編寫代碼,因此我對它的工作原理並不十分熟悉,但是本質上,在單擊Combobox時,它在ComboBox下方的TableLayoutPanel的同一面板內添加了一個ListBox,它覆蓋了正常下拉。

不幸的是,TableLayoutPanel阻止了ListBox在添加時完全可見,並且僅顯示一項。 目的是使它看起來像普通的ComboBox,它會下拉以覆蓋其下面的所有控件。

有什么方法可以讓TableLayoutPanel中的控件與TableLayoutPanel重疊,以使其按我的意願工作? 我想避免由於TableLayoutPanel增長而容納ListBox的任何控件移動。

來自控件的相關代碼:

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的建議,我想出了一個解決方案。 該表單不能重新設置大小,但是會自動調整大小,因此如果用戶在Windows中更改其DPI,它看起來就可以了。

為解決此問題,我將控件從TableLayoutPanel中移到了TableLayoutPanel的父級中的任意位置。 在表單加載時,我將TableLayoutPanel的坐標與單元格中的空白面板相加,以使控件位於頂部。 這滿足了我的需要,但感覺就像是在跳動。

更好的解決方案可能是使用Control.PointToScreen和Control.PointToClient方法,但是我無法獲得這些方法來給我正確的坐標。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM