1

Hello all I am slowly learning c#, and I have this problem:

I want to make a function that sets all panels not visible and then set one as visible given to me from a string variable.

public void setMeVisible(string PanelName)
{
    PageMainScreen.Visible = false;

    PageNewRegistration.Visible = false;

    PageSelectedPatient.Visible = false;

    ["PanelName"].Visible = true;  // in this line I want to set the value of
    //  PanelName.Visible=true.
    // what is the format that I must put PanelName?
}
Liam
  • 27,717
  • 28
  • 128
  • 190
  • luckly there is no eval in c# :D – giammin Nov 15 '13 at 16:17
  • 2
    [windows solution](http://stackoverflow.com/questions/1536739/c-sharp-get-control-by-name) – Liam Nov 15 '13 at 16:20
  • @Liam for the win! :) – crthompson Nov 15 '13 at 16:23
  • Apologies, the PanelName WILL contain a panel name 100%, I will have put it myself, so if the new registration button is pressed all I write is setMEVisible(PAgeNewRegistration). My question is: I have string a variable PanelName how do I set that panel visible? It Windows. Thank you for your help so far. – user2996809 Nov 15 '13 at 16:40

3 Answers3

3

For Windows, The simplest way is loop through all the controls and check if its a panel and set it to false. In the same loop you can check panel.Name for the pass in "PanelName" and set it to true. Something like this

foreach(Control control in form.Controls)
{
    if( control is Panel )
    {
       control.Visible = false;
       if(control.Name == "PanelName")
           control.Visible = true;

    }
}
appcoder
  • 639
  • 1
  • 9
  • 19
  • 2
    What if said Panel(s) are nested in a container **other** than the Form?...what if they are all in different containers? Then you'd need a **Recursive** search. – Idle_Mind Nov 15 '13 at 16:39
2

Use Page.FindControl for ASP.Net:

var control = FindControl(PanelName);
if (control != null)
    control.Visible = true;

If your control is nested, you can create a FindControlRecursive function, suggested by this answer:

private Control FindControlRecursive(Control root, string id)
{
    return root.ID == id
               ? root
               : (root.Controls.Cast<Control>()
                     .Select(c => FindControlRecursive(c, id)))
                     .FirstOrDefault(t => t != null);
}

Then call it by doing:

var control = FindControlRecursive(form1, PanelName); // Or another top-level control other than form1
if (control != null)
    control.Visible = true;

Use Controls.Find for a windows form application:

var control = Controls.Find(PanelName, true).FirstOrDefault();
if (control != null)
    control.Visible = true;
Community
  • 1
  • 1
matth
  • 6,112
  • 4
  • 37
  • 43
1

Looping and finding controls is not really necessary. You should add all your panels to a same container, use the Controls collection and pass in the name to get the control:

public void setMeVisible(string PanelName) {
  PageMainScreen.Visible = false;
  PageNewRegistration.Visible = false;
  PageSelectedPatient.Visible = false;
  Control c = sameContainer.Controls[PanelName];
  if(c != null) c.Visible = true;
}

If each time there is only 1 panel visible, you should use some variable to track the current shown panel and hide only this (instead of all controls as you did) like this:

Control currentShown;
public void setMeVisible(string PanelName) {
  Control c = sameContainer.Controls[PanelName];
  if(c != null) {
     c.Visible = true;
     if(currentShown != null) currentShown.Visible = false;
     currentShown = c;
  }
}

And the last, if you don't want to use the same container for all your panels. You should declare some List<Panel> to contain all your panels, then you can navigate through them easily:

List<Panel> panels = new List<Panel>();
panels.AddRange(new[]{PageMainScreen, PageNewRegistration, PageSelectedPatient});
public void setMeVisible(string PanelName) {
  var c = panels.FirstOrDefault(panel=>panel.Name == PanelName);
  if(c != null) {
     c.Visible = true;
     if(currentShown != null) currentShown.Visible = false;
     currentShown = c;
  }      
}

NOTE: Don't try complicating your UI unnecessarily. I want to mean that you should place all your panels on the same container (such as your form). That's the way we do, that way you can use the first approach, no need to loop, easy to maintain. You should also consider the Dock and the methods like BringToFront() and SendToBack() to show/hide the view.

King King
  • 61,710
  • 16
  • 105
  • 130