TabControl填充会导致TabPage中的隐藏控件错误地重新排序

时间:2020-11-11 01:59:51

标签: c# winforms tabcontrol

更改Handles的{​​{1}}属性后,尚未创建Parent的控件似乎被推到其Control TabControl的底部。看着Padding源代码,.NET调用了Padding,这似乎与它有关。

下面是说明问题的代码。每个RecreateHandle();在其下方都有一个对应的checkbox。有些标签在一开始是可见的,有些则是隐藏的。选中label复选框会使person0标签出现,但在底部显示不正确。取而代之的是,person0标签应该出现在person0复选框的正下方,这是将其添加到person0的顺序。查看屏幕截图。

代码提供了FlowLayoutPanel选项,但是必须有更好的方法。强制使用bool doWorkaround创建所有Handles似乎也不正确。

example

CreateControl()

我使用using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Windows.Forms; namespace WindowsFormsApplication3 { public class TabControl3 : TabControl { private bool doWorkaround = false; // set to true to prevent the bug protected override void OnFontChanged(EventArgs e) { base.OnFontChanged(e); int h = (int) this.Font.Height; SetPadding(new Point(h, h)); // calling this causes the Controls to re-order incorrectly } ///<summary>Setting the padding causes the TabControl to recreate all the handles, which causes the hidden handleless controls to rearrange.</summary> public virtual void SetPadding(Point pt) { // Workaround solution: remove all controls from tab pages and then add them back after. int n = TabPages.Count; Control[][] arr = null; if (doWorkaround) { arr = new Control[n][]; for (int i = 0; i < n; i++) { TabPage tp = TabPages[i]; arr[i] = tp.Controls.Cast<Control>().ToArray(); tp.Controls.Clear(); } } this.Padding = pt; // in the .NET source code, setting Padding calls RecreateHandle() if (doWorkaround) { for (int i = 0; i < n; i++) TabPages[i].Controls.AddRange(arr[i]); } } } public class CheckBox2 : CheckBox { public CheckBox2(String text, bool isChecked = false) : base() { this.Text = text; this.AutoSize = true; this.Checked = isChecked; } } public class Label2 : Label { public Label2(String text) : base() { this.Text = text; this.AutoSize = true; } } public class MyForm : Form { TabControl tc = new TabControl3 { Dock = DockStyle.Fill }; public MyForm() { this.Size = new System.Drawing.Size(600, 800); this.StartPosition = FormStartPosition.CenterScreen; TabPage tp1 = new TabPage("Page1"); FlowLayoutPanel p = new FlowLayoutPanel { FlowDirection = System.Windows.Forms.FlowDirection.TopDown, Dock = DockStyle.Fill }; p.Controls.Add(new CheckBox2("Person0")); p.Controls.Add(new Label2("Person0") { Visible = false }); p.Controls.Add(new CheckBox2("Person1", true)); p.Controls.Add(new Label2("Person1")); p.Controls.Add(new CheckBox2("Person2", true)); p.Controls.Add(new Label2("Person2")); p.Controls.Add(new CheckBox2("Person3")); p.Controls.Add(new Label2("Person3") { Visible = false }); p.Controls.Add(new CheckBox2("Person4")); p.Controls.Add(new Label2("Person4") { Visible = false }); for (int i = 0; i < p.Controls.Count; i += 2) { CheckBox cb = (CheckBox) p.Controls[i]; Label lb = (Label) p.Controls[i+1]; cb.CheckedChanged += delegate { bool b = cb.Checked; lb.Visible = b; }; } tp1.Controls.Add(p); tc.TabPages.Add(tp1); Controls.Add(tc); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); this.Font = SystemFonts.MenuFont; // to trigger the bug } } static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MyForm()); } } } 进行了测试,在这三个方面都看到了相同的行为。

0 个答案:

没有答案
相关问题