Get Parent Collection?

L

localhost

I have a UserControl with a public ArrayList as a property. I want to
use the ArrayList from the parent form, if it exists. How can I do
that?

Thanks.
 
H

Herfried K. Wagner [MVP]

* localhost said:
I have a UserControl with a public ArrayList as a property. I want to
use the ArrayList from the parent form, if it exists. How can I do
that?

How is the arraylist declared in the parent form? You can use the
usercontrol's 'FindForm' method to get a reference to the form the
control is placed on.
 
L

localhost

The ArrayList is declared as public in the containing form. I found
the FindForm method to set a reference to my container, but now what
do I do? The property does not show up with Intellisense (of course).

How do I (recursively?) iterate over a containing form properties? I
have done things to recusrively iterate over the controls collection
in forms, but the ArrayList really isn't a control, is it?



Thanks.
 
A

AlexS

Hi, localhost

if you expose array list as property you need to have a look at
Type.GetProperties method and related samples in MSDN.
If it is simple member, for example

class MyForm : Form {
...
public ArrayList al;
...
}

you can reach it like this:

MyForm mf=new MyForm();
mf.al;

Considering your property is not shown by Intellisense - maybe it is not
property or project was not compiled?

HTH
Alex
 
H

Herfried K. Wagner [MVP]

* "AlexS said:
if you expose array list as property you need to have a look at
Type.GetProperties method and related samples in MSDN.
If it is simple member, for example

class MyForm : Form {
...
public ArrayList al;
...
}

you can reach it like this:

MyForm mf=new MyForm();
mf.al;

Considering your property is not shown by Intellisense - maybe it is not
property or project was not compiled?

I would choose another approach: Provide an interface that the form must
implement, then you don't need reflection to access the member.
 
L

localhost

Thanks, I will explore Type.GetProperties, that might work.

The property can't be shown by IntelliSense because I am creating a
generic user control that will be used on forms that I have not yet
designed. The idea is to create the control, have it read from the
parent form ArrayList, and then populate control textboxes based on
the ArrayList contents in the containing parent.

Because I am currently working on the user control itself, I cannot
create an instance of a "new" form, because I don't want a "new" form.
I want to talk to the existing form that contains the control at
runtime.

This is a design-time vs run-time issue, which is why I think I need
Reflection and FindForm, I think.

Thanks for any additional help.
 
L

localhost

FindForm does not work, it always returns null. This usercontrol
exists as a discrete DLL, not a .cs included in a project with the
form. So I guess that makes it a component. So how can a component
"reach up" to its container and get information about and a reference
to that container?

Thanks.
 
L

localhost

I think I could use Type.GetProperties if I could first get a
reference to the containg form.

The UserControl exists as a .DLL that I include in new form
development projects with "MyControl myControl = new MyControl()" and
it appears on the form at run-time.

My problem is that I have to now redesign the user control to read
from an ArrayList that exists on the form that contains the control.
At design time the control has no connection to the form, and creating
a "new" form will not work because the control needs to access the
existing/containing form.

I have played a little bit more. Here is non-working code, maybe this
will illustrate what I am trying to do:

Form parentForm = this.FindForm(); // returns null
IContainer parentContainer = this.Site.Container; //
NullReferenceException
ComponentCollection parentCollection = parentContainer.Components;
for( int pcC=0 ; pcC < parentCollection.Count ; pcC++ )
{
if ( parentCollection[pcC].GetType() == typeof(Form) )
{
int fhf=pcC;
int fjfj=4; // breakpoint set but I never get here
}
}


Help!

Thanks.
 
A

AlexS

It's a bit different situation from what you described initially.

If you have ArrayList before you call new MyControl() you can modify
constructor to accept reference to array list:

mylist=new ArrayList();
....
MyControl mc=new MyControl(mylist);

In the constructor just save passed reference for future use and ... this
should work. Same could be used to pass in reference of the form.

Or you can add setter property in control, which will accept passed
reference and save it.

I am not sure now, what is the problem and why you try to this in such
complex way. Not really complex, but ...

HTH
Alex


localhost said:
I think I could use Type.GetProperties if I could first get a
reference to the containg form.

The UserControl exists as a .DLL that I include in new form
development projects with "MyControl myControl = new MyControl()" and
it appears on the form at run-time.

My problem is that I have to now redesign the user control to read
from an ArrayList that exists on the form that contains the control.
At design time the control has no connection to the form, and creating
a "new" form will not work because the control needs to access the
existing/containing form.

I have played a little bit more. Here is non-working code, maybe this
will illustrate what I am trying to do:

Form parentForm = this.FindForm(); // returns null
IContainer parentContainer = this.Site.Container; //
NullReferenceException
ComponentCollection parentCollection = parentContainer.Components;
for( int pcC=0 ; pcC < parentCollection.Count ; pcC++ )
{
if ( parentCollection[pcC].GetType() == typeof(Form) )
{
int fhf=pcC;
int fjfj=4; // breakpoint set but I never get here
}
}


Help!

Thanks.




I would choose another approach: Provide an interface that the form must
implement, then you don't need reflection to access the member.
 
L

localhost

The forms I create put important and dynamic information in an
Arraylist. The UserControl contains text boxes that must be updated
by the information in the parent ArrayList. If I only pass the
ArrayList to the UserControl at instantiation, it will only work once
and will not be continuously updated.

The code in the UserControl now looks like this:

private void UpdateMe()
{
foreach ( PropertyInfo propInfo in
this.FindForm().GetType().GetProperties() )
{
if ( propInfo.Name == "parentList" )
{
this.myList = (HybridDictionary)propInfo.GetValue( null , null
);
}
}
}

This works when fired by the ParentChanged event. My initial problem
was that I was doing the above from the UserControl constructor. At
that point in the object lifecycle, the control had no parent. Moving
the UpdateMe() call to ParentChanged makes it work.

So now I can successfully read the parent's collection in my
component.


Now I still do not understand how to go the other way and write to the
ArrayList from the UserControl - how can I do that?

Thanks.
 
A

AlexS

There is no need to pass reference more than once. You should note, that for
such objects like ArrayList - when used as parameters they are passed by
reference. It means that after you get reference you always have access to
latest data in array list through it. And also you can modify contents of
array list using same reference. Take a good note - reference to object is
not the object content.
I would suggest to check C# Programming Reference - chapters on value and
reference types and pointers. You will see from examples there that what you
want to do could be done in much simpler and more flexible way.

HTH
Alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top