[英]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.