重写Windows(Form)控件TableLayoutPanel问题
我有一个派生自 TableLayoutPanel 的类。此类构成表格更正(网格 3x8)并在某些单元格中添加一些复选框。所有这些都是通过重写函数 InitLayout() 来完成的。
public class TableLayoutPanelHours : TableLayoutPanel
{
protected override void InitLayout()
{
RowCount = 3;
ColumnCount = 8;
// Set some column and row styles
RowStyles[0].SizeType = SizeType.Percent;
RowStyles[0].Height = (100 / RowCount);
// ... etc ...
// ... create checkbox with the name checkbox1
Controls.Add(checkbox1, 1, 1); // Put in cell 1x1
// ... etc ...
}
}
构建完成后,可以从VS2010的工具箱中获取该控件。
然后,将控件放在一个简单的 Windows 窗体上,会发生一些我无法忍受的事情: - 设计模式下控件尚未化妆。 TableLayoutPanel 显示默认的 2x2 网格,并且复选框位于一个奇怪的位置。运行后,控件显示正确(3x8 网格,复选框位于正确位置) - 并且:在窗体的InitializeComponent() 中,我看到出现以下几行:
//
// tableLayoutPanelHours1
//
this.tableLayoutPanelHours1.ColumnCount = 8;
this.tableLayoutPanelHours1.ColumnCount = 3;
this.tableLayoutPanelHours1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
// ....
我例外,这些行在Windows 窗体的InitializeComponent() 中不可见,但为什么会发生这种情况?
谢谢。
I have a class which derived from the TableLayoutPanel. This class makeup the tabel corrects (grid 3x8) and add some checkboxes in some cells. All this is done by overriding the function InitLayout().
public class TableLayoutPanelHours : TableLayoutPanel
{
protected override void InitLayout()
{
RowCount = 3;
ColumnCount = 8;
// Set some column and row styles
RowStyles[0].SizeType = SizeType.Percent;
RowStyles[0].Height = (100 / RowCount);
// ... etc ...
// ... create checkbox with the name checkbox1
Controls.Add(checkbox1, 1, 1); // Put in cell 1x1
// ... etc ...
}
}
After building, the Control is available from the Toolbox of VS2010.
Then, putting the control on a simple Windows Form, some things are happen that I don't userstand:
- the control is not makeup yet during design mode. The TableLayoutPanel is displaying the default 2x2 grid and checkboxes are on a strange place. After runtime, the control is displaying correctly (3x8 grid with Checkbox on the correctly places)
- And: in the InitializeComponent() of the Form, I see these lines appears:
//
// tableLayoutPanelHours1
//
this.tableLayoutPanelHours1.ColumnCount = 8;
this.tableLayoutPanelHours1.ColumnCount = 3;
this.tableLayoutPanelHours1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
// ....
I have excepted that these lines are not visible in the InitializeComponent() of the Windows Forms, but why is this happen?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你正在与 TLP 的设计者进行斗争。这是一个自定义的,您可以通过它在设计模式下的行为方式清楚地看到这一点。使用InitLayout()方法来初始化TLP是不正确的,为时已晚。您应该在构造函数中执行此操作。
但这仍然无法满足您的需求,TLP 设计者在初始化为 2x2 时对行数和列数进行了硬编码。而且它无法处理在设计时更改它的代码(就像您在 InitLayout 中所做的那样),没有可监听的事件。你将不得不放弃那个设计师。
应该没问题,因为您已经按照您想要的方式初始化了 TLP。使用 [Designer] 属性回退到 ControlDesigner。如果这对你的控制来说是困难的,那么你将不得不创建你自己的设计师。使用 Reflector 查看内部 TableLayoutPanelDesigner 类以开始使用。请注意,这不是一个简单的设计师。
您会在 InitializeComponent 中看到这些属性分配,因为这些属性上的 [DefaultValue] 特性声明了不同的默认值。您可以通过向类添加私有 ShouldSerializeRowCount (和 ColumnCount)方法来解决此问题。返回 false 以防止属性被序列化。
You are doing battle with the designer for TLP. It is a custom one, as you can clearly see by the way it behaves in design mode. Using the InitLayout() method to initialize the TLP is not correct, it's too late. You should do it in the constructor instead.
But that still won't get you what you want, the TLP designer hard-codes the number of rows and columns when it initializes to 2x2. And it can't handle code changing it at design time (like you did in InitLayout), there are no events to listen to. You will have to give up on that designer.
Should be okay since you already initialize the TLP the way you want it. Use the [Designer] attribute to fall back to ControlDesigner. If that's hardship for your control then you will have to create your own designer. Use Reflector to look at the internal TableLayoutPanelDesigner class to get a start on that. Beware that it isn't a simple designer.
You see those property assignments in InitializeComponent because the [DefaultValue] attribute on those properties declares a different default. You can fix that by adding a private ShouldSerializeRowCount (and ColumnCount) method to your class. Return false to prevent the property from being serialized.