c# - 将大小更改传递给子控件的问题
问题描述
我正在开发一个具有如下分层界面的 WinForms 应用程序:
忽略面板 A。旁边我有一个带有 2 个选项卡的 TabControl。在第二个选项卡的 TabPage 上,我在顶部有一些用于过滤数据的控件,在其下方有面板 B,它是一个 FlowLayoutPanel,它显示来自数据库的记录列表。每条记录都显示在面板 C 中,面板 C 包含各种文本字段,具体取决于记录的内容。
加载时 UI 看起来相当不错(但请参阅下面的问题 #2)。我正在努力解决的第一个问题是正确处理主窗口的调整大小事件。当用户拖动主窗口的一侧使其变宽时,主窗体会调整 TabPage 和 Panel B 的大小,然后调用 Panel B 上的方法来调整其内容的大小。TabPage 顶部的控件根据其设置自动均匀地分布在顶部。到目前为止,一切都很好。
面板 B 遍历其 C 面板列表,调整每个面板的宽度。(稍后我将为 C Panel 添加代码以相应地调整每个文本字段的宽度。)
但目前,我遇到了两个可能相关的问题:
我似乎无法让 C 面板改变它们的宽度。我最初希望通过正确的 AutoSize、AutoScroll 等设置,我可以得到我想要的,但是当这不起作用时,我决定添加一个 resize 事件处理程序来获得更多控制权。这目前无法正常工作。
甚至在调整大小之前,我将面板 B 的宽度设置为适合 TabPage,并将面板 B 的 FlowDirection 设置为 FlowDirection.TopDown,但是一旦有足够的 C 面板超过面板 B 的高度,面板 B 变为双倍宽度,其中有第二列 C 面板。我真正想要的是添加一个垂直滚动条来滚动“TopDown”列表。
当我将面板 B 的 AutoScroll 设置为 true 时,我没有得到垂直滚动条(这是我期望的 TopDown 面板);相反,我得到了一个水平滚动条,面板向右增长!所以我关闭了自动滚动。
这是一些相关的代码:
class MainForm : Form
{
private int priorHeight;
private int priorWidth;
private System.Windows.Forms.TabPage MyTabPage;
private SelectableListPanel PanelB = null;
...
private void OnResize(object sender, EventArgs e)
{
this.SuspendLayout();
int vDiff = this.Height - priorHeight;
int hDiff = this.Width - priorWidth;
MyTabPage.Height += vDiff;
MyTabPage.Width += hDiff;
PanelB.Height += vDiff;
PanelB.Width += hDiff;
// tell PanelB to resize its record panels
PanelB.PropagateResize(hDiff);
ResumeLayout(false);
PerformLayout();
priorHeight = this.Height;
priorWidth = this.Width;
}
}
class SelectableListPanel : FlowLayoutPanel
{
protected List<Panel> panels = new List<Panel>();
public SelectableListPanel(List<Panel> Panels) : base()
{
FlowDirection = FlowDirection.TopDown;
AutoScroll = false;
AutoSize = false;
panels = Panels;
}
...
public void PropagateResize(int hDiff)
{
foreach (Panel genPanel in panels)
{
genPanel.Width += hDiff;
// TODO: genPanel.PropagateResize(hDiff)
}
}
}
有什么想法/建议吗?
解决方案
想发布一些代码,让我可以测试我在评论中收到的建议。我的演示程序是这样做的:
这是它的代码:
public Form1()
{
Panel BluePanel;
Panel OrangePanel;
Panel GreenPanel;
List<Panel> PurplePanels;
InitializeComponent();
SuspendLayout();
// Field 1
TextBox f1 = new TextBox();
f1.Text = "Main Form";
f1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
f1.Font = new Font("Microsoft Sans Serif", 14F, FontStyle.Regular,
GraphicsUnit.Point, (byte) 0);
f1.Location = new Point(12, 12);
f1.Multiline = true;
f1.Name = "Field1";
f1.Size = new Size(460, 32);
f1.TabIndex = 0;
// BluePanel
BluePanel = new Panel();
BluePanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
BluePanel.BackColor = Color.Blue;
BluePanel.Location = new Point(12, 50);
BluePanel.Name = "BluePanel";
BluePanel.Size = new Size(460, 402);
BluePanel.TabIndex = 1;
// Field 2
TextBox f2 = new TextBox();
f2.Text = "Blue Panel";
f2.Anchor = f1.Anchor;
f2.Font = f1.Font;
f2.Location = f1.Location;
f2.Name = "Field2";
f2.Size = new Size(BluePanel.Width - 24, f1.Height);
f2.TabIndex = 0;
BluePanel.Controls.Add(f2);
// OrangePanel
OrangePanel = new Panel();
OrangePanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
OrangePanel.BackColor = Color.Orange;
OrangePanel.Location = new Point(f2.Left, f2.Bottom + 6);
OrangePanel.Name = "OrangePanel";
OrangePanel.Size = new Size(BluePanel.Width - 24, BluePanel.Height - (f2.Bottom + 6 + 12));
OrangePanel.TabIndex = 1;
BluePanel.Controls.Add(OrangePanel);
// Field 3
TextBox f3 = new TextBox();
f3.Text = "Orange Panel";
f3.Anchor = f1.Anchor;
f3.Font = f1.Font;
f3.Location = f1.Location;
f3.Name = "Field3";
f3.Size = new Size(OrangePanel.Width - 24, f1.Height);
f3.TabIndex = 0;
OrangePanel.Controls.Add(f3);
// GreenPanel
// GreenPanel = new FlowLayoutPanel();
// GreenPanel.FlowDirection = FlowDirection.LeftToRight;
GreenPanel = new Panel();
GreenPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
GreenPanel.AutoScroll = true;
GreenPanel.AutoSize = false;
GreenPanel.BackColor = Color.Green;
GreenPanel.Location = new Point(f3.Left, f3.Bottom + 6);
GreenPanel.Name = "GreenPanel";
GreenPanel.Size = new Size(OrangePanel.Width - 24, OrangePanel.Height - (f3.Bottom + 6 + 12));
GreenPanel.TabIndex = 1;
OrangePanel.Controls.Add(GreenPanel);
// PurplePanels
PurplePanels = new List<Panel>();
for (int i = 0; i < 10; i++)
{
Panel PurplePanel = new Panel();
PurplePanel.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
PurplePanel.BackColor = Color.Purple;
PurplePanel.Size = new Size(GreenPanel.Width - 24, 32 + 24);
PurplePanel.Location = new Point(12, 6 + (i * (32 + 24 + 6)));
PurplePanel.Name = "PurplePanel" + i.ToString();
PurplePanel.TabIndex = i;
// Fields
TextBox fi = new TextBox();
fi.Text = "Purple Panel " + i.ToString();
fi.Anchor = f1.Anchor;
fi.Font = f1.Font;
fi.Location = f1.Location;
fi.Name = "Fieldi" + i.ToString();
fi.Size = new Size(PurplePanel.Width - 24, f1.Height);
fi.TabIndex = 0;
PurplePanel.Controls.Add(fi);
GreenPanel.Controls.Add(PurplePanel);
PurplePanels.Add(PurplePanel);
}
ResumeLayout(false);
PerformLayout();
}
要查看 FlowLayoutPanel 有什么不同,只需取消注释 Green Panel 部分中的相关行,并注释掉“GreenPanel = new Panel();” 线。在那里您会看到 FlowDirection.LeftToRight 不会产生所需的结果。
我还想向@Jimi 和@LarsTech 大声疾呼,因为他们为我指明了正确的方向。
推荐阅读
- python - 有谁可以解释 flask_jwt_extended access_token 是如何工作的?
- php - 如何在代码中使用某些接口实现
- python - 尝试使用 python 在 CSV 上查找特定信息时出错(可能与 pandas 相关)
- ios - 避免延迟播放来自其他应用程序的音乐的音频(Soundcloud)
- cypress - Cypress TypeError: this[name] is not a function at AsyncSeriesHook.lazyCompileHook
- atom-editor - 无法在 Mac 上可视化 atom 中的行尾
- android - React Native:原生模块 NativeUnimoduleProxy 试图覆盖 NativeModulesProxy。检查 MainAppication.java 中的 getPackages() 方法
- python - pip install pyinstaller 失败,显示 SSL 错误
- python-3.x - 如何修复可用于 CVGridsearch 的 loky 进程
- php - 如何在谷歌表格 API 上使用过滤器在 ASC 中显示数据值?