I have a tPageControl on a form, and have made a nice 'welcome page' as a new ttabsheet at design time for the user to start off with. However, if the user closes this tab, I would like the option to bring it back, as it was in originally (much like the welcome page in the Delphi IDE). This seems like a simple problem...
When the tab closes, the original sheet is freed and set nil. I tried creating the sheet again by name (e.g. tabsheet1 := ttabsheet.create) and assigning it to the pagecontrol, but none of the original components from the sheet are there anymore...
I know designing the welcome page as a separate form, creating it when I need it and slapping it into a new tabsheet would work... but I was just wondering if there was a way to do it with the design time tabsheet.
Thanks all!
Rusty
As Serg mentioned, you can just set the tabsheet's TabVisible property to false when you want to hide the page. The page control will switch to the next tab if it needs to, the tab will disappear, and the user won't be able to switch back to it until you change TabVisible back.
Re-creating the design-time tab sheet will be quite a challenge because all the information describing its layout is embedded in the DFM resource for your form. It's not like there a separate resource for each tab, so you'd need to read the resource, extract the portion relevant to the tab, and then get ReadComponent to build a new instance; nothing in Delphi is designed to make that very easy, so you should consider other options.
The easiest solution would probably be to design your welcome page on a frame; I've found frames to be a little more cooperative than full-fledged forms when it comes to re-parenting them.
Another option is to create the entire tab in code. GExperts has a tool to make that pretty easy. Select the tab sheet, and then choose DExperts's "components to code" command. That places some code on the clipboard, and you can paste it into a function in your program. The code will contain everything required to re-create the selected components in code instead of building them from the DFM resource. Then, you can use that function to not only re-create the tab after it's been closed, but to create the tab in the first place. That way, you can be assured that you're creating the same thing both times.
The reason your attempt at re-creating the tab didn't work is that the name of the variable used to hold a reference to the form doesn't really define anything. All you did was create a brand new TTabSheet. The fact that you stored a reference to it in the same variable that used to hold a reference to the old tab is irrelevant. (But please feel free to give that variable a more meaningful name; all "TabSheet1" says is that it's the first tab you put on your form, way back when you first started working on this project.)
Rob's right about what's going on, and about using frames to fix it. Bit if you want a simpler solution, you could try just making the tab invisible whan the user closes it, instead of freeing it.
Thank you all for your comments and suggestions. A couple notes :
I tried the GEExperts option (pretty nice, I havent used this one before!) : however, it did not preserve many design time settings (font size and color for example)...also there were components with glyphs that didnt get saved....
Changing the visibility of the tabsheet doesnt seem to work either; the pagecontrol doesn't seem to know what to display, even after calling .Refresh ...it shows whatever is underneath your window.
Anyhow, I might investigate the frames option, but likely will just move the components to a new form and call it when needed...
Thanks again!
Related
This would save loads of time when testing a specfic section which is far down the form and the form is configured in a Wizard View.
I just wondered whether there is a querystring parameter or xpath setting to put in xforms-inspector which will save us endless clicks on the Next button! So far the best way I have found is to disable the Wizard View so that the form shows vertically.
This isn't currently supported, but it sounds like a worthwhile feature to have, and I've created an RFE for this feature.
I don't understand why you have to click next all the time, you should be able to just click on the section name in the table of contents.
Delphi-version5.
I have a file comparison app I am putting together and it has a Left and Right Panel on the main form. Each panel (pnlLeft and pnlRight) has an identical range of Controls and events only separated by name. i.e btnCheckLeft(... and btnCheckRight(... and I am having problems keeping the code changes synched between the two Panels.
I am wondering if I can make a single Panel (on a separate Form) with all of the controls and events and then at runtime, copy it twice, once for the pnlLeft an the other, the pnlRight to the main form. On that single Form, I can manage the coding just the once instead of trying to duplicate everything.
During the process, set the Align and the Event names to apply to each copy as in...
The first copy to the blank main form...
pnlLeft.Align:=alLeft;
pnlLeft.Button1Click(Sender)...
the second copy
pnlRight.Align:=alLeft;
pnlRight.Button1Click(Sender)...
How or is that possible? I think I need a Component of the full Panel, but I am not skilled enough to create a Component of this complexity yet.
I checked this
how to copy all the TLabels parented with a TPanel on delphi to another TPanel?
and this
Duplicating components at Run-Time
but don't think either will do what I need.
Thanks for anything you can help with.
The solution to your problem does not lie in duplicating a control at run time. Instead, design a TFrame object. Put all your panel-specific code on there, including any controls it needs. Then, simply instantiate it twice, and give each one a different name. Then you can refer to LeftPanel.btnCheck and RightPanel.btnCheck.
on a form I need a first set of UI controls at process start, later I only need a second set of components. I put the set for process set #1 on a first panel , after finish process step #1 I start to hide panel #1, is ther any better way from UI design guide lines ?
I would use Frames instead of Panels. You can design Frames at design-time just like Forms, and then create instances of your Frames at run-time as needed. So create your first Frame (you can even place it on the Form at design-time) and then at run-time, when ready you can destroy the first Frame instance and create an instance of the second Frame.
Using panels like you describe is a very common and very respectable way to proceed. Nothing wrong with doing it that way.
Another often used idiom is a page control with hidden tabs. So, make a page control. Add two tab sheets. Set TabVisible to False for both tab sheets. Then at run time set the ActivePage property of the page control to specify which page is shown to the user.
The page control approach is really rather similar to using panels. It's perhaps marginally easier to work with at design time, but much comes down to personal preference.
I have a PageControl with seven TabSheets and all Tabs are hidden and I change pages using pcMain.ActivePage:=tsAuto (tsMarine etc.) It works, but the Change and Changing events do not get fired.
I tried the following, but it only works when Tabs are visible.
http://delphi.about.com/od/adptips2005/a/bltip0205_5.htm
I also wrote a procedure using pcMain.SelectNextPage(True) incrementing and decrementing a counter and the SelectNextPage but it also only works when Tabs are visible.
Anyone have a suggestion how to get around this issue? I need to use the AllowChange of the Changing-Event to prevent leaving a page if a Database is in an Edit-state.
The code from About.com should work fine. It explicitly calls CanChange and Change, which in turn call the event handlers, if any are assigned. They do not check whether the requested tab is visible.
Furthermore, SelectNextPage should also work. You just have to make sure you pass False for the second parameter to tell it to disregard tab visibility. (If you don't specify a value for the second parameter, the default value is True.)
If neither technique works, then you need to dig deeper because the problem is elsewhere.
One other thing you can try is to simply not assign a new active page if there are pending database changes. You're the one deciding to go the next page, after all. If you know in advance that it shouldn't happen, then don't attempt it in the first place.
I'm looking for a way of implementing a sort of inset caption before a set of tabs, something like this:
The tab set is not supposed to be multi-line, will only be horizontal and laid out at the top. However it should be correctly scrollable when there are too many tabs.
I fear I'm going to be restricted here with regard to using third-party controls, but I could use subclassing on the standard TTabControl to add the necessary changes to the standard looks and behaviour. (I don't need it to be TPageControl, because it's only the specific arrangement of the tabs that I am interested in.)
Maybe there's some way of implementing this with craftily arranged combination of standard controls, which, despite my endevours, has escaped me.
Basically, any ideas or pointers are welcome.
Oh, and additional requirement is, it should blend well with desktop themes.
Granted some time has passed, but I recently needed this style and found you can do it with the TMS Software TAdvOfficePager. It has a property FixedTabs, which I set to 1 in this case. It also has an OnChanging event where you can prevent access to a tab, in this case I used AllowChange := (ToPage > 0); Lastly, I set the first tab to disabled.
Then just style the first tab different than the rest and you can have something like this:
Have you tried to make the first tab to be the caption you want.
With some additional logic you can restrict the selection of this tab.
I don't know if you can control the style of each tab individually to make the first one look as it is not the tab.
Here is crafty arrangement of controls that will work. I have done this sort of thing in the past. Best of all it automatically handles scrolling of tabs.