Help: Getting variable's declaring class through reflection

M

Mark

Given a reference to a variable, is there a way to find the class that
originally allocated that variable.

More specifically, I have a method that takes a control as a parameter. I
want to be able to determine the form class that initially allocated it. I
am not looking for the control's Form object. I need the class (or instance
of the class) that holds the control (and the form).
 
M

Marc Gravell

OK; that's how you are trying to do it; but can you explain what you
are trying to do?

I suspect that the answer is "no" (at least, without lots of hacks),
but if you describe what you are trying to achieve, I/we/somebody may
be able to suggest a suitable option...

Marc
 
M

Mark

I need the following statement to help me get at the private "components"
variable of the class/form where the control was declared:

public static void Required_Validating(object sender,
System.ComponentModel.CancelEventArgs e)

{

Control ctrl = (Control) sender;


MemberInfo[] mem = typeof(MyApp.frmMain).GetMember("components",
MemberTypes.Field, BindingFlags.Instance | BindingFlags.NonPublic |
BindingFlags.DeclaredOnly);
....
}

Right now I have to hard code MyApp.frmMain. I need to obtain the class that
declared the control dynamically at run-time.

Please no lectures on accessing private variables of a class -- just a way
to do this.
 
M

Mark

Figured it out. The following function can be used as a generic Validating
event handler to process required fields. It needs an ErrorProvider
component on the form to report the error.

public static void Validating_Required(object sender, CancelEventArgs e)

{

Control ctrl = (Control) sender;

Form frm = ctrl.FindForm();

IContainer container = (IContainer) frm.GetType().GetField("components",
BindingFlags.Instance | BindingFlags.NonPublic |
BindingFlags.DeclaredOnly).GetValue(frm);

foreach (Component comp in container.Components)

if (comp is ErrorProvider)

{

if (ctrl.Text.Trim().Length == 0)

{

((ErrorProvider) comp).SetError(ctrl, "Required field.");

e.Cancel = true;

}

else

((ErrorProvider) comp).SetError(ctrl, null);

break;

}

}
 
M

Marc Gravell

(IContainer) frm.GetType().GetField("components",
BindingFlags.Instance | BindingFlags.NonPublic |
BindingFlags.DeclaredOnly).GetValue(frm);

*shudder*

If the forms are in your control, I really think you'd be much better
off exposing this formally, perhaps by an interface that all your
forms implement that simply makes the components visible as an
interface property; then you simply do something like:


IFoo foo = ctrl.FindForm() as IFoo;
if(foo != null && foo.Components != null) {
// your code, using foo.Components
}

Just a thought; the other approach will probably work a lot of the
time, but it is very brittle...

Marc
 
J

Jack Jackson

*shudder*

If the forms are in your control, I really think you'd be much better
off exposing this formally, perhaps by an interface that all your
forms implement that simply makes the components visible as an
interface property; then you simply do something like:


IFoo foo = ctrl.FindForm() as IFoo;
if(foo != null && foo.Components != null) {
// your code, using foo.Components
}

Just a thought; the other approach will probably work a lot of the
time, but it is very brittle...

Marc

I think the OP wants code in a control to be able to find an
ErrorProvider object that was dropped on the form. Unfortunately I
have not been able to find any way to do this, since the collection of
components dropped on the form is Private.

The way I have gotten around this is to make my base Form class create
an ErrorProvider at runtime. My base class form implements an
interface that includes a function that returns a reference to the
ErrorProvider. Then controls can use Control.FindForm, cast to my
interfrace, and then make the call to return a reference to the
ErrorProvider.
 

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