Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Container on a Form 1

Status
Not open for further replies.

SitesMasstec

Programmer
Sep 26, 2010
508
Brasil
Hello colleagues!

I have created a form and put a Container (from the Form Controls toolbar) on the form.

Container1_izgqil.jpg


Then, from the same toolbar I pick a ComboBox and throwed it inside the Container (well, I thought I did). Well, when I moved the Container in the Form, the ComboBox does not change its position, as it is on the Form and not inside the Container.

Also, the Container is behind other control (Grid1). There is no BringToFront property...

Thank you,
SitesMasstec
 
Hi,

If you want add some object to container then - key down CTRL and click to container.


mJindrova
 
To add an object to the inside of a container, you need to put the container into "edit mode" - also know as "fuzzy green line mode". To do so, right-click on the container and choose "Edit". The container will then take on the nominal fuzzy green border, and you can drop objects into it.

This applies to any container-type control, such as pages, columns, etc. not just actual containers.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
SitesMasstec,
At the risk of blowing this up... have you subclassed the VFP base classes first?

For instance, instead of "ContainerClass" have you subclassed that as "MyContainerClass" (or I use "ContainerClassBase" as the name for my subclasses).

This is critical because as you utilize the inheritance capabilities of VFP (and if you're not, you might as well use FPW2.6 for your project).

This may not seem to make any sense now, and you don't need to "understand" it to use it, but you will have massive rework later if you haven't subclassed your base classes first.


Best Regards,
Scott
MSc ISM, MIET, MASHRAE, CDCAP, CDCP, CDCS, CDCE, CTDC, CTIA, ATS, ATD

"I try to be nice, but sometimes my mouth doesn't cooperate.
 
SitesMasstec said:
There is no BringToFront property...
No, but there is a bring to front menu item:

bringtofront_ua6ttu.jpg


PS: No matter what else you also put into the container, you can also easily solve the overlap problem by shrinking the container itself. Arrange all controls inside so they start in the left top corner of the container and only make the container as large to fit the gottom right part of the inner controls, then you're good to go. Just notice if you bring the container to the top with the Format menu item, also the invisible part of it is in front of a grid cell, so that could not be clicked. So the straight forward solution is not even to bring controls to the front or back, but to position them side by side without overlap.

Chriss
 
Well, as I was confused, I decided to implement the solution in 2 phases. First, without using the Container.
After I got the desired result, I will go to second phase, to implement the use of Container (or a popup small window).

Well, I am working in the first phase, I
RepetirValores_lnyrx9.jpg
failed:


My actions:
- I clicked on "Passageiro 1" (Page1 of Pageframe1) first, put some data in the fields, the right clicked the page and the result was as expected.

- Then I clicked on "Passageiro 2" (Page2 of Pageframe1), put some data in the fields, the right clicked the page and the result was the same as when I right clicked on "Passageiro 1" (Page1 of Pageframe1), which is wrong!

In the Pageframe1, Object Page2, Procedure RightClick, I have:
Code:
NumberPax="2"
this.Parent.Parent.lblOndeRepetir.Refresh
this.Parent.Parent.cboOndeRepetir.Refresh
this.Parent.Parent.lblOndeRepetir.Visible= .T.
this.Parent.Parent.cboOndeRepetir.Visible= .T.
this.Parent.Parent.cboOndeRepetir.SetFocus


In the right side of the form, I have the Object lblOndeRepetir initially not visible, with the Caption property:
Code:
="Copiar valores do passageiro " + NumberPax


And bellow the label, I have the Object cboOndeRepetir initially not visible, with the Procedure Init:
Code:
With This
   IF NumberPax<>"1"
	   .AddItem("para Passageiro 1")
   ENDIF
   IF NumberPax<>"2"
	   .AddItem("para Passageiro 2")
   ENDIF
   IF NumberPax<>"3"
	   .AddItem("para Passageiro 3")
   ENDIF
   IF NumberPax<>"4"
	   .AddItem("para Passageiro 4")
   ENDIF
   IF NumberPax<>"5"
	   .AddItem("para Passageiro 5")
   ENDIF
   .AddItem("Cancelar")
   .ListIndex=1
EndWith

Note: NumberPax is a PUBLIC variable.



Thank you,
SitesMasstec
 
A label.caption property set to an expression like ="Copiar valores do passageiro " + NumberPax gets evaluated when the label is created, at form start. When NumberPax changes, that doesn't change the label caption, that's all to it.

So, if you want to change the caption, you can't just change NumberPax, if you want anything that initially had an expression including NumberPax to change when NumberPax changes, you'd need to program something that
1. Knows where NumberPax should influence properties like caption or other properties
2. Knows the original expressions (the property caption, once intialized doesn't have that expression anymore, it's replaced by the evaluation of it)


The only propert that works as you expect the cpation to work, too, is the controlsource property, that's special in that it doesn't set the controlsource to the evaluated value, but the value property, so the controlsource stays the expression it was and is durig the lifetime. Since a label has no controlsource that's the end of the story unless you program something as suggested, or use a control like a textbox and degrade it to look like a label by removing the border, setting the background transparent and then use the controlsource mechanism for that.

Chriss
 
Yes, Chris!
Great! I changed the label for a text box, with some properties (Border: None, BackStyle: Transparent, etc) and I achieved the desired result, as the variable NumberPax changing when I right click on different pages of the framepage.

But the ComboBox doesn't have it contents changed if, for example, I right click on Page2.

The ComboBox, Procedure Init has:
Code:
With This
   IF NumberPax<>"1"
	   .AddItem("para Passageiro 1")
   ENDIF
   IF NumberPax<>"2"
	   .AddItem("para Passageiro 2")
   ENDIF
   IF NumberPax<>"3"
	   .AddItem("para Passageiro 3")
   ENDIF
   IF NumberPax<>"4"
	   .AddItem("para Passageiro 4")
   ENDIF
   IF NumberPax<>"5"
	   .AddItem("para Passageiro 5")
   ENDIF
   .AddItem("Cancelar")
   .ListIndex=1
EndWith

So, if I right click on Page2, NumberPax=2, and the ComboBox should present the items:
para Passageiro 1
para Passageiro 3
para Passageiro 4
para Passageiro 5

(to copy some data to a page, except to itself).



Thank you,
SitesMasstec
 
Yes, init is the initalization event, it always only runs once when an object or control is created. That's the very nature of initialization, it's done once and then the obkject is initialized and will never be iniotialized again.

There is a refresh event, that happens when you call thisform.refresh for all controls on the form, so you could use the Refresh event to do something when you refresh the form. This is all simply as it's named.

Notice: You'll also need to clear the combobox from all items or you get more and more items with each refresh.

Chriss
 
Ok, I cleared the method in the ComboBox and put it in the RightClick procedure of all pages (Page1...Page5) of the Pageframe and it works as desired:

Code:
This.Parent.Parent.cboOndeRepetir.Clear   
With This.Parent.Parent.cboOndeRepetir
   IF NumberPax<>"1"
	   .AddItem("para Passageiro 1")
   ENDIF
   IF NumberPax<>"2"
	   .AddItem("para Passageiro 2")
   ENDIF
   IF NumberPax<>"3"
	   .AddItem("para Passageiro 3")
   ENDIF
   IF NumberPax<>"4"
	   .AddItem("para Passageiro 4")
   ENDIF
   IF NumberPax<>"5"
	   .AddItem("para Passageiro 5")
   ENDIF
   .AddItem("Cancelar")
   .ListIndex=1
EndWith

So, step 1 concluded with your valuable help!

I will try to put the TextBox (used for a label) and ComboBox on a Container ou a popup window.


Thank you,
SitesMasstec
 
Not a good idea, the idea was to put the code from the combobox init to the comobox refresh and then in the pages rightclick you can just call THISFORM.REFRESH() which cascades to all controls refresh code.

Chriss
 
I will change to it, Chris, and let's see.

I was afraid to refresh all form, because it has many fields.

Is there any difference between Refresh and Refresh()?


Thank you,
SitesMasstec
 
The brackets just make clear you call a method and don't access a property. It's an unwritten law or convention to do that to make that clear to the reader, VFP won't care.

SitesMasstec said:
I was afraid to refresh all form, because it has many fields.

There's a god point about this. It's not bad to refresh the whole form. You're right even without any code in the Refresh of other controls it does something to all of them, but it doesn't take much time. Mainly everything stays and if a refresh causes a changed display, that was even necessary, otherwise refrehing of display values sometimes only happens when a user clicks on a textbox, for example.

Calling the form refresh opens up the possibility to use the Refresh of other controls which need it, too, without needing additional code in the page rightclick events. If you feel more comfortable and the combobox is the only control actually having refresh code, you can call that directly, it's not forbidden. Then it's still just one line per page rightclick and not the whole rigamarole.

Chriss
 

Good! It works fine, thanks Chris!

I put this in the ComboBox, Procedure: Refresh:
Code:
This.Clear
SET CONFIRM ON
WITH this
   IF NumberPax<>"1"
	   .AddItem("para Passageiro 1")
   ENDIF
   IF NumberPax<>"2"
	   .AddItem("para Passageiro 2")
   ENDIF
   IF NumberPax<>"3"
	   .AddItem("para Passageiro 3")
   ENDIF
   IF NumberPax<>"4"
	   .AddItem("para Passageiro 4")
   ENDIF
   IF NumberPax<>"5"
	   .AddItem("para Passageiro 5")
   ENDIF
   .AddItem("Cancelar")
   .ListIndex=1
ENDWITH
SET CONFIRM OFF

And in the Page1...Page5 from Pageframe1, Procedure RightClick

Code:
NumberPax="1"
TextoRepetir="Copiar valores do passageiro " + NumberPax

THISFORM.REFRESH() 

this.Parent.Parent.txtOndeRepetir.Visible= .T.
this.Parent.Parent.cboOndeRepetir.Visible= .T.

this.Parent.Parent.cboOndeRepetir.SetFocus

I used SET CONFIRM ON/OFF in the ComboBox in order for the user to have to press <enter> after selecting an item, but it have no effect...



Thank you,
SitesMasstec
 
Remove SET CONFIRM ON/OFF from the Refresh. you want to SET CONFIRM ON in the GotFocus and maybe SET CONFIRM OFF in the LostFocus event.

Dong both in Refresh and ending on SET COFIRM OFF, it's only on for split seconds during which you create the items and mostly it's of, that's not working, of course.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top