13 Replies - 1586 Views - Last Post: 02 June 2012 - 04:35 PM Rate Topic: -----

#1 Alyssa Saila  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 72
  • Joined: 07-January 12

How To Find All Nested Controls Throughout Entire Project

Posted 02 June 2012 - 08:56 AM

I am a new to all of this.

I am needing a way to loop through every form and every control on that form.

I am needing to find everything ..-be it forms, controls, nested forms, or nested controls within controls.

Regardless of type, and regardless of how deeply nested the form within a form control within a control might be.

I was hoping to add them all to a List<Control> or whatever array necessary so that I can access them accordingly.

I simply need access to everything everywhere, and the only way I've been able to access anything without directly
calling these controls explicitly by name is to instantiate first.

My code beneath doesn't call the need for everything of everything, but everytime I try to call stuff blind or by string name I get caught
up in the world of instantiation (and I wind up with controls I cannot instantiate because I cannot locate them blindly by string name).

..So in essence I just figured what the heck, why not get everything of every type regardless of deeply nested so that I will always be able to
instantiate new controls based on string names no matter what.







What I am doing is trying to change tabPages within tabControls (amongst manipulate other controls elsewhere by the control string name).

Some tabControls are nested within others, and some tabControls are nested in forms as well.

My plan is to add absolutely everything into an array when my app starts.

By doing this (I hope), I can then reloop through that array instantiating as I need to (for anything I need to).

Beneath is an example of what I mean, but of course it would loop through every form and every nested control or form.

My ultimate goal is to change tabPages with one function call
private void button1_Click(object sender, EventArgs e)
{
	LoadInterface("tabControllerNameHere", "tabPageNameHere");
}



The reason I want to implement one function call to change a tabPage is so that I won't have to paste
a lot of code in every new button_Click I create.

With this, I simply paste LoadInterface("tabControllerNameHere", "tabPageNameHere"); into any button click and it changes my tabPage.

One last thing, the reason I request all controls and everything else is because I began creating other one call functions like this,
but I find myself stuck trying to instantiate nested things and controls I can't point to programmatically without explicitly calling them by name.

Of course with one function call like this, the whole point is to simply pass the string names in, and simply have it find the control by name, instantiate
that control, and do whatever I want to that control accordingly (regardless of type or how nested that is) through one function call.

Beneath is a working example, but it only works with tabPages (1-4) in tabControl1.

tabControl1 is not instantiated (and is called explicitly), just couldn't figure out how to instantiate that name also (so the first arg in my function call
is really not doing anything right now.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Reflection;

namespace Nested_Tab_Controls
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.tabControl1.Size = new Size(655, this.ClientRectangle.Height);
            showPage1.Click += new EventHandler(ShowPageOne);
            showPage2.Click += new EventHandler(ShowPageTwo);
            showPage3.Click += new EventHandler(ShowPageThree);
            showPage4.Click += new EventHandler(ShowPageFour);
        }
		//************************************************************************************************************
        public void ShowPageOne(object sender, EventArgs e)
        {
            LoadInterface("tabControl1", "tabPage1");
        }
        public void ShowPageTwo(object sender, EventArgs e)
        {
            LoadInterface("tabControl1", "tabPage2");
        }
        public void ShowPageThree(object sender, EventArgs e)
        {
            LoadInterface("tabControl1", "tabPage3");
        }
        public void ShowPageFour(object sender, EventArgs e)
        {
            LoadInterface("tabControl1", "tabPage4");
        }
		//************************************************************************************************************
        public void LoadInterface(string interfaceControlTabHolder, string loadTabInterface)
        {
            TabPage newInstantiatedTabPage = new TabPage();			
			
            List<Control> newTabPageCtrlList = new List<Control>();

            foreach (TabPage newTabCtrl in tabControl1.Controls)
            {       
                if (newTabCtrl.Name == loadTabInterface)
                {
                    newInstantiatedTabPage = (TabPage)Activator.CreateInstance(newTabCtrl.GetType());

                    // Assign newInstantiatedTabPage Data From newTabCtrl
                    newInstantiatedTabPage.Name = newTabCtrl.Name;
                    newInstantiatedTabPage.BackColor = newTabCtrl.BackColor;
                    newInstantiatedTabPage.Size = new Size(newTabCtrl.Width, newTabCtrl.Height);

                    // Collect Filled Contents From newTabCtrl
                    foreach (Control inheritTabPageCtrl in newTabCtrl.Controls)
                    {
                        newTabPageCtrlList.Add(inheritTabPageCtrl);
                    }

                    // Assign Those Filled Contents Into newInstantiatedTabPage
                    for (int newTabPageCounter = 0; newTabPageCounter < newTabPageCtrlList.Count; newTabPageCounter++)
                    {
                        newInstantiatedTabPage.Controls.Add(newTabPageCtrlList[newTabPageCounter]);
                    }

                    // Get newTabCtrl Index Position
                    int tabIndexPos = tabControl1.TabPages.IndexOf(newTabCtrl);

                    // Remove newInstantiatedTabPage
                    tabControl1.TabPages.Remove(newTabCtrl);

                    // Add newInstantiatedTabPage Back
                    tabControl1.TabPages.Insert(tabIndexPos, newInstantiatedTabPage);

                    // Set Focus On newInstantiatedTabPage
                    tabControl1.SelectedIndex = tabIndexPos;
                }
            }
        }
		//************************************************************************************************************
    }
}



Is This A Good Question/Topic? 0
  • +

Replies To: How To Find All Nested Controls Throughout Entire Project

#2 Alyssa Saila  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 72
  • Joined: 07-January 12

Re: How To Find All Nested Controls Throughout Entire Project

Posted 02 June 2012 - 09:17 AM

As a new fresh mind to programming..

I knew I wanted to simply change a tabPage with a button click.

So I thought okay, this should work... let me simply make this button go to tabPage3 on my child form...
private void button1_Click(object sender, EventArgs e)
{
	newChildForm.tabControl1.tabPage1.SelectedIndex = 2;
}




NOPE! : )

Turns out I have to:
-first loop through all of my forms to find that form
-then instantiate a new instance of that child form
-then loop through all of the controls of that child form to find the tabControl holder
-then instantiate a new instance of that tabControl holder
-then check if the tabPage I'm trying to manipulate even exists
-then instantiate a new instance of that tabPage
-then get the index position of that that tabPage
-then loop through properties of that tabPage (size, color, controls nested within it etc..)
-then remove that tabPage
-then add that tabPage back in the position that I found it
-then add all of those controls back to it that I collected it from it
-and then finally select that tab

Of course I'm hoping there is a better cleaner easier way to do all of this.

This why I simply want one function to perform all of this (if there is in fact no other way around all of this).

If anyone has a better idea I'm all ears. I'm new, and open to any suggestions.
All of this instantiating a removing and adding is getting crazy.

Was This Post Helpful? 0
  • +
  • -

#3 Momerath  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1010
  • View blog
  • Posts: 2,444
  • Joined: 04-October 09

Re: How To Find All Nested Controls Throughout Entire Project

Posted 02 June 2012 - 09:17 AM

Your form has a Controls attribute which holds all the controls that are contained within that form. Each control also has a Controls attribute which holds all the controls that are contained within that control. Recursively iterate through them all to get your collection.
Was This Post Helpful? 1
  • +
  • -

#4 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5481
  • View blog
  • Posts: 11,762
  • Joined: 02-June 10

Re: How To Find All Nested Controls Throughout Entire Project

Posted 02 June 2012 - 09:20 AM

I have some SERIOUS doubt about such a need.

I want you to ask yourself this: Do any of the other professional developers need to do this?

If they don't, then you really need to re-think your approach and why you think you need to do this.


Quote

I simply need access to everything everywhere,


Hell no. I have never seen any application that had to access everything everywhere. This violates so many basic principals of OOP that I don't know where to begin. It is the opposite of what you need. Each object only needs to know about itself and the minimalist amount of data that it is responsible for and nothing else.


Quote

and the only way I've been able to access anything without directly calling these controls explicitly by name is to instantiate first.

Well of course you have to instantiate a thing before you can use it. It doesn't exist before you instantiate it.


Quote

(amongst manipulate other controls elsewhere by the control string name)

NO. Wrong. Bad. Don't try to manipulate the GUI controls from all over hell and gone. You change a property. You can make part of that property's set{} method the altering of a GUI so the GUI reflects the true state of the value. You change the GUI in one place only.

Quote

What I am doing is trying to change tabPages within tabControls

Ok. So what's the problem? The TabControl has a collection of pages. Use the .SelectPage method

Quote

With this, I simply paste LoadInterface("tabControllerNameHere", "tabPageNameHere"); into any button click and it changes my tabPage.

Don't worry about the tab pages name. Just locate the tab with the text you want "Settings", "User", "Groceries"... whatever... then select that page. So if the user clicks the "Groceries" button, loop through your pages, find the one with the text "Groceries" and then select that one.

Your goal to locate everything everywhere is just so far off base that I would never consider using it... would never consider helping someone figure out how to do this... would never hire someone that was doing something this wonky... You problem isn't how do you do this: Your problem is that you need to design your app much better and in line with proper Separation of Responsibility and "black box" concepts.

Please read through a few of my tutorials that are aimed at getting rookies like yourself thinking along the right path of small coding units that are autonomous and independent. (blog link in signature block)
Was This Post Helpful? 1
  • +
  • -

#5 Alyssa Saila  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 72
  • Joined: 07-January 12

Re: How To Find All Nested Controls Throughout Entire Project

Posted 02 June 2012 - 10:10 AM

Okay so stupid approach. I get that. I'm a good sport.

Consider that entire approach completely erased from memory.

So now, starting from square one....

If you wanted a button_click to show tabPage2 located in a nested tab control on form2...

private void button1_Click(object sender, EventArgs e)
{
	// How would you do it?...
}


Was This Post Helpful? 0
  • +
  • -

#6 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5481
  • View blog
  • Posts: 11,762
  • Joined: 02-June 10

Re: How To Find All Nested Controls Throughout Entire Project

Posted 02 June 2012 - 11:18 AM

tabControl1.SelectTab(1);


All collections are zero-indexed. So the first page is index 0, the second page is index 1 and so on. Therefore tabPage2 being the second page added would be element 1

If you want to find a page by the text displayed on the tab I'm pretty sure this should work.


          string openThisPage = "Yogi";
            foreach (TabPage tabPage in tabControl1.TabPages)
            {
                if (tabPage.ToString().ToLower() == openThisPage.ToLower())
                {
                    tabControl1.SelectTab(tabPage);
                }
            }



the TabPage's .ToString() method will return the text on the tab. I tend to do a lot of my simplistic compares of text by taking both sides .ToLower() so it doesn't fail "Yogi" to "yogi"
Was This Post Helpful? 1
  • +
  • -

#7 Alyssa Saila  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 72
  • Joined: 07-January 12

Re: How To Find All Nested Controls Throughout Entire Project

Posted 02 June 2012 - 11:55 AM

What if I'm not sure if "Yogi" is in tabControl1?

Is there any way to perform this same type of search throughout tabControl2 or tabControl3 simultaneously etc...?

Or am I getting caught up in the mess I was initially trying earlier?

Was This Post Helpful? 0
  • +
  • -

#8 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5481
  • View blog
  • Posts: 11,762
  • Joined: 02-June 10

Re: How To Find All Nested Controls Throughout Entire Project

Posted 02 June 2012 - 12:08 PM

So not only do you have multiple tab pages, but you also have multiple tab controls with multiple pages each?

You'll just need to extend the loop example I provided.

foreach  tabControl
    foreach tabPage on that tabControl
       is this the page I want?


Is this more of the mess you started with?
Hard for me to say because I don't really know what it is you're trying to build or what your criteria is. But it does sort of sound like you are having to search through a lot... maybe because of program architecture, maybe not. I just don't have enough to go on.
Was This Post Helpful? 1
  • +
  • -

#9 Alyssa Saila  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 72
  • Joined: 07-January 12

Re: How To Find All Nested Controls Throughout Entire Project

Posted 02 June 2012 - 01:07 PM

I was trying to create a window switch navigation process by providing navigation butttons to different tabs with additional buttons and things on each tab of course.

Some tab controls will be nested, and some nested controls will be nested a step further perhaps.

Generally, I just wanted a way select that tab by a string name in the button_Click call.

Looping through the "nestedness" is where I'm getting all turned around.
Was This Post Helpful? 0
  • +
  • -

#10 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5481
  • View blog
  • Posts: 11,762
  • Joined: 02-June 10

Re: How To Find All Nested Controls Throughout Entire Project

Posted 02 June 2012 - 01:17 PM

View PostAlyssa Saila, on 02 June 2012 - 02:07 PM, said:

I was trying to create a window switch navigation process by providing navigation butttons to different tabs with additional buttons and things on each tab of course.


Can't even picture it. Can you do a screen grab to make it more clear?
Was This Post Helpful? 1
  • +
  • -

#11 Alyssa Saila  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 72
  • Joined: 07-January 12

Re: How To Find All Nested Controls Throughout Entire Project

Posted 02 June 2012 - 02:58 PM

A form with tabs with a menu feel that loads different tab menus with button_Click.

But I can't get to the nested tab controls (because some main tabs will have sub tabs and so forth).

My plan is to call each switch like so....
private void button1_Click(object sender, EventArgs e)
{
    LoadTabPage("Yogi);
}


public void LoadTabPage(string openTabPage)
{
	foreach (TabPage tabPage in tabControl1.TabPages)
	{
	  if (tabPage.ToString().ToLower() == openThisPage.ToLower())
	  {
		  tabControl1.SelectTab(tabPage);
	  }
	}
}




I've already declared myself wonky & ridiculous. So please don't be afraid to hurt my feelings if you feel think this is approach is stupid. To be quite honest I'm completely open to any criticism, I just wanna get this thing done. Like I said I'm a good sport. I have a feeling there is a much easier way to display different pages, forms, panels, tabs etc with button clicks, but this is the only thing I can come up with.

However, calling it with one function like so...
 "LoadTabPage(openTabPage);"



...is crucial because I'm going to be making a lot of buttons & pages, that switch and toggle all over the place (so having one function call to one method handle all of this elegantly would be awesome).

Here is a screenshot example:
Posted Image

This post has been edited by Alyssa Saila: 02 June 2012 - 03:03 PM

Was This Post Helpful? 0
  • +
  • -

#12 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5481
  • View blog
  • Posts: 11,762
  • Joined: 02-June 10

Re: How To Find All Nested Controls Throughout Entire Project

Posted 02 June 2012 - 03:37 PM

This is starting to get into the realm of recursive logic.
Kind of like when you are looking for files and folders on a hard drive: You can have a folder, with files and folders in it, that can have folders and files in that , that can have folders and files in that...

So you are going to have to recursively search every control within a tabpage to see if it is also a tabcontrol then search its tab pages etc.

If you're starting to think this is bit convoluted, you're right. But so is this GUI you're showing.

It might be better to just assign the tab page to a given button's .Tag property - assuming all these pages aren't being created at runtime. So if the goal is to have 5 or 6 "quick open" buttons to specific tab pages then clicking a button would then get the tag of the button and use that to open the specified tabpage.

If all of these are being created at runtime then you are back to recursive searching.

Quote

...is crucial because I'm going to be making a lot of buttons & pages, that switch and toggle all over the place


Is that really the best choice?
You've already discovered how this is becoming more complex than you can handle. Maybe this just isn't the best model you can be using.

What about a treeview? Make a two-pane window, when someone clicks on the node in the treeview of the left pane, the full gui for that object appears in the right pane.
Was This Post Helpful? 1
  • +
  • -

#13 Alyssa Saila  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 72
  • Joined: 07-January 12

Re: How To Find All Nested Controls Throughout Entire Project

Posted 02 June 2012 - 04:21 PM

You're right.

I need to go back to the drawing board and think all of this through.

You've been helping me pretty much all day today tlhIn`toq :)

I really appreciate that, and thanks for helping me clean up.

Was This Post Helpful? 0
  • +
  • -

#14 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5481
  • View blog
  • Posts: 11,762
  • Joined: 02-June 10

Re: How To Find All Nested Controls Throughout Entire Project

Posted 02 June 2012 - 04:35 PM

I know the example I described is hard to picture so here is an example.

You can see a lot of different objects in the treeview on the left.
When you click on one, the full GUI for that object is shown on the right.
Click on the scheduler and you see all the time schedule selection options.
Click on the FileEmail and you get all the email GUI
The hierarchy of the object is clear without taking a ton of space, and each level can be collapsed.

Attached Image

Lesson: When it becomes impossible to code the model you've designed, maybe the fix is to design a new model.
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1