For the past couple of days I’ve been working on an experimental IntraWeb (a.k.a., "VCL for the Web") project. Since I typically generate user interfaces dynamically, I wanted to see how that worked with IntraWeb. On the surface, it’s fairly similar to the regular VCL, but there are some important differences.
Another thing to note is that the default property values don’t always make sense. If a component looks different when you dynamically generated at runtime versus when you drop it on an IntraWeb form in the designer, take a close look at the text DFM. You’ll probably find non-default property values set by the designer. If you replicate this in your code, you should end up with a component looks the same at runtime.
With all that said, here’s some simple code to add tabs at runtime to an existing tab control:
uses Graphics, IWContainerBorderOptions;
for iPage := Pred(TabControl.Pages.Count) downto 0 do begin
iPage, iTabTop, iTabHeight, iTabWidth: integer;
// need to have a design-time page to copy sizing properties from
Assert(TabControl.Pages.Count > 0);
iTabTop := TIWTabPage(TabControl.Pages).Top;
iTabHeight := TIWTabPage(TabControl.Pages).Height;
iTabWidth := TIWTabPage(TabControl.Pages).Width;
for iPage := 0 to 2 do begin
NewTab := TIWTabPage.Create(TabControl);
NewTab.BorderOptions.NumericWidth := 0;
NewTab.BorderOptions.BorderWidth := cbwNumeric;
NewTab.BorderOptions.Style := cbsNone;
NewTab.BorderOptions.Color := clNone;
NewTab.Color := clWebWHITE;
NewTab.Top := iTabTop;
NewTab.Width := iTabWidth;
NewTab.Height := iTabHeight;
// WordPress changes the single quote to a typographic quote here, so cutting
// and pasting the next two lines won't work. Sorry; I haven't figured out how
// to stop that
NewTab.Name := 'DynamicPage' + IntToStr(iPage);
NewTab.Title := 'Page ' + IntToStr(iPage);
NewTab.Parent := TabControl;
// TabOrder determines the order of tabs (really!) in this control
// It must be set *after* Parent
NewTab.TabOrder := iPage;
Alignment may not work as expected, either. If I build on this example by creating a control, parenting it to the tab sheet, and setting the Align property to alClient, that control’s size or position doesn’t actually change.
Finally, there is the issue of layout managers. If you use TIWTemplateProcessorHTML or TIWLayoutMgrHTML, there will not be a placeholder in your template for your dynamically generated component. There is probably a way around this, but I have not fully investigated the issue yet. One possible solution would be to do the dynamic component generation inside of a custom IntraWeb control.