我有一个包含TableLayoutPanel的表单,其中包含各种控件和标签。其中一个是从ComboBox继承的自定义控件,它具有额外的自动完成行为(在任何文本上自动完成而不是从左到右)。我没有为这个控件编写代码,所以我不太熟悉它是如何工作的,但基本上点击了Combobox,它在ComboBox下面添加了一个ListBox,在TableLayoutPanel的同一个Panel中,这涵盖了正常的下拉。
不幸的是,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();
}
图片:
答案 0 :(得分:0)
根据TaW的建议,我想出了一个初步的解决方案。此表单不具有可调整大小,但会自动调整大小,以便用户在Windows中更改其DPI时看起来没问题。
要解决此问题,我将控件从TableLayoutPanel移出到TableLayoutPanel的Parent中的任意位置。在表单加载时,我总结了TableLayoutPanel的坐标和单元格中的空面板,我想让控件位于顶部。这符合我的需求,但感觉就像一个kludge。
更好的解决方案可能是使用Control.PointToScreen和Control.PointToClient方法,但是我无法通过这些方法为我提供正确的坐标。