Show/Hide controls Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Nunki
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 235
Joined: Fri Sep 14, 2012 8:26 am
Location: Kontich, Belgium
Contact:

Show/Hide controls

Post by Nunki »

Hi Guys,
Little struggle with show & hide of controls. I start with the xrc file that contains two checkboxes which are - for alignment reasons - in a vertical box sizer, which is part of a gridbag sizer on a panel. Based on the data after display of the mdi window, I hide the checkboxes that are irrelevant. So far so good. Now when the data changes, I re-call the routine that does the hiding/showing and the checkbox re-appears but not in the original location. As if it was removed from the vertical box sizer and now added to the gridbag sizer (upper left corner) see image.
dossier.png
dossier.png (34.12 KiB) Viewed 4658 times
dossier2.png
dossier2.png (26.93 KiB) Viewed 4658 times
Anyone who can tell we why i see this effect and how to remedy this ?

regards,
Nunki
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Show/Hide controls

Post by ONEEYEMAN »

Hi,
Can you post the initialization code? I presume this is in the wxFrame-derived class and not wxDialog? So just wxFrame constructor...
Or just answer - did you call Layout() prior to hiding the checkboxes?

Thank you.
Nunki
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 235
Joined: Fri Sep 14, 2012 8:26 am
Location: Kontich, Belgium
Contact:

Re: Show/Hide controls

Post by Nunki »

Hi OneEyeMan,

I'll try to highlight the flow for you. So to answer your question, The constructor is tcDossier::tcDossier which calls BuildScreen() which calls SetTab1() That calls the AdjustMcReno() method that does the actual hiding. So as it is now, Layout() is called in BuildScreen() after SetTab1().
Are you implying that hiding them before Layout is called will actually remove them from their sizer ?

regards,
Nunki

Code: Select all

tcDossier::tcDossier(tcBaseDossier *hBase,tcList *pRec,teAction eAct)
{
 ....
 switch(this->eAct)
   {
    case ACT_INSERT: // Insert new dataset member
                    ......

                     this->BuildScreen();
                     this->SetTitle("Nieuw dossier");
                     break;
    case ACT_UPDATE: // Change existing dataset member
                     this->pD = new tcDossiers(pRec);
                     this->BuildScreen();
                     this->SetTitle(this->pD->GetId());
                     break;
    case ACT_DELETE: // Remove dataset member
                     this->pD = new tcDossiers(pRec);
                     this->pD->Delete();
                     break;
   }

}

void tcDossier::BuildScreen(void)
{
 bool bLoaded;

 bLoaded = wxXmlResource::Get()->LoadObject(this, rApp.pMainWindow,wxT("ID_DOSSIER"),wxT("wxMDIChildFrame"));
 if (bLoaded)
  {
   .....
   this->SetTab1();
   //this->SetTab2();
   this->Move(30,30);
   this->Update();
   if (GetSizer())  GetSizer()->SetSizeHints(this);
   this->Layout();
   this->Show();
  }
 Refresh();
}

void tcDossier::SetTab1(void)
{
 ...

 this->AdjustMcReno();

....
}

void tcDossier::AdjustMcReno(void)
{
 wxCheckBox *hCheck;
 wxChoice *hChoice;

 // On the safe side, get latest selection
 hChoice = XRCCTRL(*this, "DOSS_RELTYPE", wxChoice);
 this->pD->SetReltype(hChoice->GetStringSelection());

 switch( GetAbstractType(this->pD->GetReltype()) )
  {
   case AT::UNKNOWN: hCheck = XRCCTRL(*this, "DOSS_MC", wxCheckBox);
                     hCheck->Hide();
                     hCheck = XRCCTRL(*this, "DOSS_RENO", wxCheckBox);
                     hCheck->Hide();
                     break;
   case AT::COMPANY: hCheck = XRCCTRL(*this, "DOSS_MC", wxCheckBox);
                     hCheck->Show();
                     hCheck->SetValue(this->pD->GetMc());

                     hCheck = XRCCTRL(*this, "DOSS_RENO", wxCheckBox);
                     hCheck->Hide();
                     this->pD->SetReno(false);
                     hCheck->SetValue(false);
                     break;
   case AT::PERSON: hCheck = XRCCTRL(*this, "DOSS_MC", wxCheckBox);
                    hCheck->Hide();
                    this->pD->SetMc(false);
                    hCheck->SetValue(false);

                    hCheck = XRCCTRL(*this, "DOSS_RENO", wxCheckBox);
                    hCheck->Show();
                    hCheck->SetValue(this->pD->GetReno());
                    break;
  }

 Refresh();
}
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Show/Hide controls

Post by doublemax »

Just call Layout() after hiding or showing controls. You may want to set the wxRESERVE_SPACE_EVEN_IF_HIDDEN flag when adding those items to the sizer to avoid unpleasant jumping of controls.
Use the source, Luke!
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Show/Hide controls

Post by ONEEYEMAN »

Hi, Nunki,
Nunki wrote: Hi OneEyeMan,

I'll try to highlight the flow for you. So to answer your question, The constructor is tcDossier::tcDossier which calls BuildScreen() which calls SetTab1() That calls the AdjustMcReno() method that does the actual hiding. So as it is now, Layout() is called in BuildScreen() after SetTab1().
Are you implying that hiding them before Layout is called will actually remove them from their sizer ?

regards,
Nunki
What I'm trying to say is that when you create a control with the (wxDefaultPosition,wxDefaultSize) it will be created in the top-left corner of the parent window.
When you call Layout() all controls will be properly positioned and sized.

So, if you call Hide() right after control creation they will be hidden in the top-left corner of the parent, simply because Layout() call is laying out controls which are present on the screen. It doesn't care about hidden ones.

So the flow that you should do is:

1. create the control
2. add it to sizer
3. call layout
4. hide the control.

Hope I made myself clear.

Thank you.

P.S.: Also, check doublemax' reply about the option he mentioned.
Nunki
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 235
Joined: Fri Sep 14, 2012 8:26 am
Location: Kontich, Belgium
Contact:

Re: Show/Hide controls

Post by Nunki »

Hi OneEyeMan,

Perfectly clear, thanks. Indeed doublemax has a point, I already tried using the layout after showing the control but have forgotten about the wxRESERVE_SPACE_EVEN_IF_HIDDEN flag. Will try and test your as well as doublemax's solution.

Which makes me wonder, there is no real book on mastering wxWidgets like there are on access, java etc by 'o reilly. Apart from the obvious manual by Julian Smart & Kevin Hock. More like a hand on book with lots of items like on this forum.

Learned a new thing about wxWidgets today,
I'm a happy man :-)

regards,
Nunki
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Show/Hide controls

Post by ONEEYEMAN »

Hi, Nunki,
The book you are talking abouit is seriously outdated. Just look at the year it was published.
The best way to learn wxWidgets is by looking at the samples and the documentation. Just keep in mind - some samples are also having problem(s). ;-)

Thank you.
coderrc
Earned some good credits
Earned some good credits
Posts: 141
Joined: Tue Nov 01, 2016 2:46 pm

Re: Show/Hide controls

Post by coderrc »

ONEEYEMAN wrote:Hi, Nunki,
The book you are talking abouit is seriously outdated. Just look at the year it was published.
As much as I don't disagree, I still think there is some value to spending the 3 or 4 hours it takes to read the wxwidgets book when you are starting from zero wxwidgets experience. As old as it is, it still gives a good "broad strokes" of why things are done the way they are and how it all comes together.
Post Reply