【发布时间】:2020-09-02 15:53:11
【问题描述】:
这是为 Winforms / C# 顺便说一句。
所以我正在制作自己的 ComboBox,只是随便玩玩。 项目 List 基本上是一个 Panel,它位于 ComboBox 控件的下方或上方,具体取决于其高度和位置。
只要我使用 AnchorStyle Top / Left 作为我的用户控件,这将按预期工作。
一旦我切换到顶部/右侧样式,我的列表面板的位置就会中断。好的,有道理,我的用户控件的位置点随着不同的锚样式而变化,那么我如何使用我的 usercontrol.LocationChanged 事件将我的面板调整到新位置?不工作。也许是因为事件的顺序?还是位置的来源会根据给定的 AnchorStyles 而改变?
不管怎样,我有点失落。不幸的是,我在这里找不到类似的案例,因此提出了这个问题。
这是我的 DropDownPanel(实际上是我的“列表”):
private Panel DropDownPanel()
{
Panel DropDownPanel = new Panel() {
Width = this.Width,
Height = 200,
BackColor = _skin.TextBoxBackColor,
BorderStyle = BorderStyle.FixedSingle,
ForeColor = _skin.TextBoxForeColor,
Visible = false,
AutoScroll = false
};
DropDownPanel.HorizontalScroll.Enabled = false;
DropDownPanel.HorizontalScroll.Visible = false;
DropDownPanel.HorizontalScroll.Maximum = 0;
DropDownPanel.AutoScroll = true;
DropDownPanel.Leave += DropDownPanel_Leave;
return DropDownPanel;
}
这是我的 userControl 加载事件:
private void GbComboBox_Load(object sender, EventArgs e)
{
_dropDownPanel = DropDownPanel();
this.Parent.Parent.Controls.Add(_dropDownPanel);
RelocateDropDownPanel();
_dropDownPanel.BringToFront();
ApplyItems(_items);
}
以及我对位置的计算:
private void RelocateDropDownPanel()
{
if (_dropDownPanel != null)
{
int initLocY = this.Parent.Location.Y + this.Location.Y + this.Height + _dropDownPanel.Height;
int fullHeight = this.FindForm().Height;
Point p = new Point();
if (initLocY < fullHeight)
{
p = new Point(this.Parent.Location.X + this.Location.X, initLocY - _dropDownPanel.Height);
}
else
{
p = new Point(this.Parent.Location.X + this.Location.X, initLocY - _dropDownPanel.Height - this.Height);
}
_dropDownPanel.Location = p;
}
}
【问题讨论】:
-
所有者绘制一个标准的组合框不是更简单吗?你会遇到更多的问题,而不仅仅是找到正确的位置。您的 Combo 的父级(以及容器本身)对面板的可见性施加的限制如何?当父母改变时? (还有很多……)
-
@Jimi 你是完全正确的,我知道这一点。但是我想暂时搁置一些替代方法,尽管我真的很感激它们!
-
从这里开始:
this.Parent.Parent.Controls.Add(_dropDownPanel);。这当然是错误的。您需要处理组合框的重新定位(LocationChanged、Resize、SizeChanged等)和PointToScreen()-PointToClient()列表面板的新位置。列表面板的父级可以是表单(或桌面,看看你是否可以让它工作,这很有趣:)。在那之后,锚就不是你的大问题了。