AnnNeedsHelp

Hi, searched the forum, found something that wouldn't work, so I'm asking for some help.

I'd like to find all forms in my application after clicking on a menu item, so I can do something with all of them. That would be something like:

foreach (Form f in AllformsOfApplication)
{ dosomething(f);
}

Note: not just the open forms like with Application.OpenForms but something like Application.AllForms (if only it would exist...)

Thanks for the help!


Re: Windows Forms General foreach(Form f in AllformsOfApplication)

Ethan Pack

I don't know of any built in functionality that would support this. My suggestion would be to create a collection class of type System.Windows.Forms.Form and add each form to the collection when you instantiate it. Then you could foreach through the collection, knowing that all forms in the application would be in there.

Good luck!

Ethan




Re: Windows Forms General foreach(Form f in AllformsOfApplication)

James Curran

Note: not just the open forms like with Application.OpenForms but something like Application.AllForms (if only it would exist...)

Application.OpenForms is conceivable. Application.AllForms is a phyisical impossiblity.

As an analogue, imagine a property Application.AllInts, which should include not just all ints that you've declared, but all int that you might declare. It would have to be infinite.

For an example closer to what you've asked, imagine an project which include three forms: form1.cs, form2.cs, and form3.cs. Form1 opens two different instances of Form2. Do both instances of Form2 appear in AllForms or just one, and if one, which one Alternately, if no instance of Form3 is created, does it appear in the AllForms And if so, what instances of Form3.

The problem, which often happened with class like forms, where you general only create one instance, is a blurring of the line between a class and an object.






Re: Windows Forms General foreach(Form f in AllformsOfApplication)

AnnNeedsHelp

I knew the first answer was the way to go, but since I'm not really the expert I searched on the forum and found this:

List<Form> allForms = new List<Form>();
Assembly asm = Assembly.GetExecutingAssembly();

foreach (Type t in asm.GetTypes())
{
if(t is Form)
{
allForms.add(t);
}
}

I've been fighting with it all afternoon, but I won't work.




Re: Windows Forms General foreach(Form f in AllformsOfApplication)

James Curran

t is a Type object.  It holds infomation about a Form class.  It is not an instance of that class.

Hence instead of  "   if(t is Form)"   you want "if (t.IsSubclassOf(typeof(Form)))"

However, that only gets you one line further, because next up, "allForms.add(t);" is going to fail.

Now, there are two way we can go here:

List<Type> allForms = new List<Type>();   and "allForms.add(t);"  which will give you a List of Type objects describing all the forms in your assembly....OR...

List<Form> allForms = new List<Form>();  and "allForms.Add(Activator.CreateInstance(t) as Form);"   which give you a list of (new, hidden) Forms. (These are all the same Form classes as in your application, but they are not the same Form objects as you are using in your application.)

If you tell us what you are planning on doing with this list, prehaps we can show you a better way of going about it.

 






Re: Windows Forms General foreach(Form f in AllformsOfApplication)

nobugz

I have to agree with James. It doesn't make any sense to call dosomething() with a form reference that hasn't been created yet. You'll just get a NullReferenceException. More-over, you can't enumerate all the forms that you might have access to, an assembly that contains a form might not have been loaded yet. Only Application.OpenForms makes sense.





Re: Windows Forms General foreach(Form f in AllformsOfApplication)

AnnNeedsHelp

I'll try to be brief... I'm starting from an Open Source project which has a mechanism for translations built in. It's kind of complicated so I'm not going to explain that, but I know how it works.

One of the things it does is write all of the contents of the Text properties for all controls on a form to a table in the database. A tool is provided to then translate them so the translations then are automatically loaded and used. Now, the problem is that it only does that after the form has been opened. So if I want to have a full list of all text to be translated I need to start the program, open all forms, subforms, messageboxes, ... That not only consumes an awful amount of time, I always miss some of them.

I would like to use what's already there by using the translation function (the 'dosomething') on each form, launching it by clicking on a menu item.

The other option is writing an other program that just searches for the Text properties in the C#-files. Just thought the first option would be easier, especially since it takes in consideration the controls that were already translated in an older version.

Am I making any sense here




Re: Windows Forms General foreach(Form f in AllformsOfApplication)

nobugz

Take a look at the .resx files, they'll contain the designer generated value of the Text property. Note that the Winres.exe utility uses this to help you to localize your apps.





Re: Windows Forms General foreach(Form f in AllformsOfApplication)

AnnNeedsHelp

For those who have local help, I found this:
How to: Access Properties of Files for Specific Types of Projects -
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_extvbcs/html/498fd515-1a05-4ee2-89d2-e5babcde034e.htm

It's the code for an add-in that lists the FileName property for each file in the project, it then determines if the file has a .cs or .vb extension. If it does, the Filesize and DateCreated property values are also displayed.

It actually works, but I don't know anything about add-ins. It displays all the info mentioned above in messageboxes. I could just make it write to a file instead or do whatever with it, but what I can't figure out is how to run it a second time...

I did Tools->Add-in manager, clicked on the add-in and the ok-button. It ran just fine, but it won't do that again.

Question: how to ...

I'm going to check out if I can integrate this as simple code behind a button.




Re: Windows Forms General foreach(Form f in AllformsOfApplication)

AnnNeedsHelp

Two days of research, but this gives me the files in my solution:

EnvDTE80.DTE2 dte2;
dte2 = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.8.0");
Solution soln= dte2.Solution;
Project proj;
ProjectItems projItems;
ProjectItem projItem;
Property prop;
proj = soln.Projects.Item(1);
projItems=proj.ProjectItems;

for(int i=1; i<=projItems.Count;i++)
{
projItem = projItems.Item(i);
MessageBox.Show(projItem.Name);
}

Anyone any idea how to know what kind of files these are I only need the forms. I could just check for strings "class xxx : Form" in the .cs files, but there has to be a more elegant way...




Re: Windows Forms General foreach(Form f in AllformsOfApplication)

AnnNeedsHelp

I just realized my question somehow got posted in the wrong forum. Could anyone help me with the following:

I'm trying to list all forms in my application in runtime. I thought I found it (look at http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=1094731&SiteID=1), but this gives me the forms from another application. Don't know why though...

Am I looking in the right direction or should I do something totally different

Thanks for your help!!!