Hi Yasutaka,
I wrote a simple iterator class for you. You can use it to get the
compontets your controls host. You may use the code as is, but bare in mind
that it will work only for the controls generated with VS wizard because it
looks for the *components* member. And of course if you want to use it as is
I'll suggest you do do some more testing because I haven't done enough. The
code is at the end of this post.
You can use the class like this
foreach( Component c in new ComponentsIterator(control, false))
{
....
}
If the secont constructor's parameter is *false* the interator will
iterates only over the components from the controls' class
If true it will iterate over the parent classes as well.
The class:
===========
using System;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Reflection;
namespace Iterator
{
/// <summary>
/// Summary description for ComponentsEnumerator.
/// </summary>
public class ComponentsIterator: IEnumerable, IEnumerator
{
private Control mTarget;
private IEnumerator mCurrentEnumerator;
private bool mInherited;
private FieldInfo mComponentsField = null;
public ComponentsIterator(Control ctrl, bool inherited)
{
mTarget = ctrl;
mInherited = inherited;
Reset();
}
private void InitializeEnumerator()
{
mCurrentEnumerator = null;
if(mComponentsField != null)
{
IContainer components = mComponentsField.GetValue(mTarget) as
IContainer;
if(components != null)
{
mCurrentEnumerator = components.Components.GetEnumerator();
}
}
}
#region IEnumerable Members
public IEnumerator GetEnumerator()
{
return this;
}
#endregion
#region IEnumerator Members
public void Reset()
{
mComponentsField = mTarget.GetType().GetField("components",
BindingFlags.NonPublic | BindingFlags.Instance);
InitializeEnumerator();
}
public object Current
{
get
{
if(mCurrentEnumerator == null) throw new InvalidOperationException();
return mCurrentEnumerator.Current;
}
}
public bool MoveNext()
{
if(mCurrentEnumerator == null) throw new InvalidOperationException();
bool res = mCurrentEnumerator.MoveNext();
while(!res && mCurrentEnumerator != null)
{
if(mInherited)
{
mComponentsField =
mComponentsField.DeclaringType.BaseType.GetField(" components",
BindingFlags.NonPublic | BindingFlags.Instance);
InitializeEnumerator();
if(mCurrentEnumerator != null) res = mCurrentEnumerator.MoveNext();
}
else break;
}
return res;
}
#endregion
}
}
--
B\rgds
100
"Yasutaka Ito" <no****@nonexistent.com> wrote in message
news:O%****************@TK2MSFTNGP11.phx.gbl...
Thanks Iulian!
I tried this, but this always return me null. :( I'm trying the following.
1) I have Form1 with a button
2. In the button's Click() event, I'm calling my EnumerateComponents
function passing the instance of Form2.
private void button1_Click(object sender, System.EventArgs e)
{
Form2 form = new Form2();
ComponentsCollection(form);
}
public void EnumerateCollection(System.Windows.Forms.Form
anyFormInstance) {
foreach(System.ComponentModel.Component component in
anyFormInstance.Site.Container.Components)
{
MessageBox.Show(component.ToString());
}
}
I must be getting something screwed up here... would appreciate any help.
thanks!
-Yasutaka
"Iulian Ionescu" <an*******@discussions.microsoft.com> wrote in message
news:BC**********************************@microsof t.com... Read the Site of a control that exists on the form or of the form
itself. Check the Container member of the Site and it will contain a list of
available components. If you need the type of the components you will need
a reference to a IReferenceService (get it using Site.GetSevice) and use its
methods to make the query...
Hope this helps,
iulian