使控件突破面板边界
Make a control break out of panel bounds
我在为 WinForms 制作一些自定义控件时遇到了问题。当调整我的一个控件的大小时,它会以一种比面板边界 (height/width) 更长的方式被切断。此行为是预期的,但我希望此控件有所不同。无论如何,有没有办法在不打扰将这些控件与控件层次结构一起使用的人的情况下完成这项工作? Example of what i'm talking about
提前致谢。
来自 OP 的评论之一:
...I was talking about something like the ComboBox, when even though it's inside the panel, it's dropdown breaks out of the bounds of the panel...
ComboBox(ListBox)的下拉列表显示为顶级 window(在所有其他之上);因此它不是另一个控件的父级。您可以使用 MouseEnter/MouseLeave 事件将控件切换为 top-level/normal 来做类似的事情。只有当鼠标进入它时才会完全显示,并且它被更改为顶级window。
以下是此类控件的最小实现。
class AutoTopLevelPanel : Panel
{
private Control parentInternal;
private int parentIndex = -1;
private Point locationInternal;
public AutoTopLevelPanel()
{
BorderStyle = BorderStyle.Fixed3D;
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
if (parentIndex == -1)
{
parentIndex = Parent.Controls.IndexOf(this);
}
if (base.TopLevelControl != this)
{
parentInternal = Parent;
locationInternal = Location;
Location = Parent.PointToScreen(Location);
Parent = null;
SetTopLevel(true);
}
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
if (base.TopLevelControl == this)
{
SetTopLevel(false);
Parent = parentInternal;
Parent.Controls.SetChildIndex(this, parentIndex);
Location = locationInternal;
}
}
}
我在为 WinForms 制作一些自定义控件时遇到了问题。当调整我的一个控件的大小时,它会以一种比面板边界 (height/width) 更长的方式被切断。此行为是预期的,但我希望此控件有所不同。无论如何,有没有办法在不打扰将这些控件与控件层次结构一起使用的人的情况下完成这项工作? Example of what i'm talking about 提前致谢。
来自 OP 的评论之一:
...I was talking about something like the ComboBox, when even though it's inside the panel, it's dropdown breaks out of the bounds of the panel...
ComboBox(ListBox)的下拉列表显示为顶级 window(在所有其他之上);因此它不是另一个控件的父级。您可以使用 MouseEnter/MouseLeave 事件将控件切换为 top-level/normal 来做类似的事情。只有当鼠标进入它时才会完全显示,并且它被更改为顶级window。
以下是此类控件的最小实现。
class AutoTopLevelPanel : Panel
{
private Control parentInternal;
private int parentIndex = -1;
private Point locationInternal;
public AutoTopLevelPanel()
{
BorderStyle = BorderStyle.Fixed3D;
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
if (parentIndex == -1)
{
parentIndex = Parent.Controls.IndexOf(this);
}
if (base.TopLevelControl != this)
{
parentInternal = Parent;
locationInternal = Location;
Location = Parent.PointToScreen(Location);
Parent = null;
SetTopLevel(true);
}
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
if (base.TopLevelControl == this)
{
SetTopLevel(false);
Parent = parentInternal;
Parent.Controls.SetChildIndex(this, parentIndex);
Location = locationInternal;
}
}
}