views:

4012

answers:

7

I have a ChildUserControl that is loaded inside a ParentUserControl. The host page loads ParentUserControl.

I would need to access properties in ParentUserControl from the ChildUserControl.

Thanks for your time

+6  A: 

The platform / language etc isn't clear, so this answer is necessarily vague... however, in general a child control can't access properties from the parent (directly), because lots of different types of parent controls could be hosting the child control. The child shouldn't be hard-coded to a single parent, otherwise it might as well be part of the parent.

Generally, you might want to try to simply remove the requirement - it sounds like an odd design. However, some frameworks support something like this - for example, dependency properties in WPF.

An interface-based design (for the parent(s)) is one approach, but this isn't very clean. For .NET, events etc are another common way for a child to communicate with a parent - the child exposes events which different parents can consume in different ways.

Other than that, you're into the territory of testing/casting the parent (either against a class or an interface) to access details from the parent - for example:

ParentControlType parent = this.Parent as ParentControlType;
if(parent != null) {
    // access properties etc of "parent"
}

(could also use an interface here; still a bit hacky either way...)

Personally, rather than use this type of cast from the child, I'd prefer the parent to take control; the parent sets properties on the child, and listens to events (rather than the child set properties back on the parent):

// in the parent
child.SomeProperty = 132;
child.SomePropertyChangd += delegate {
    // do something at the parent
};

This way, the child doesn't know or care about the parent. All it knows is that it has properties (etc), and can notify other people to interesting changes.

Marc Gravell
A: 

Sorry for not being clear. The platform is .NET and the language is C#.

I have a single parent that hosts multiple children control. This was one way of achieving visual inheritance in C# as there were a number of UI controls that were shared among children.

By the interface design, do you suggest that both the parent and the child(ren) implement a common interface?

Only where necessary. If you have multiple parents hosting the same child control, then an interface (that all the parents implement) would be an acceptable option. Personally, I'd rather the parent took control, and set properties / subscribed to events on the child.
Marc Gravell
winform? webform? wpf? mvc?
Marc Gravell
A: 

You could use Reflection like this:

public static T GetData<T>(this Control c, string propertyName, T defaultValue){
  Type t = obj.GetType();
  var prop = t.GetProperties().FirstOrDefault(p => p.Name == propertyName);
  if(prop == null) return defaultValue;
  else {
    object val = prop.GetValue(obj, null);
    if(val == null) return defaultValue;
    else return (T)val;
  }
}

That simple extension method which extends "Control" but you can easily put this on anything (I've used it on object when I was passing anonymous classes around, which is in itself a bad idea!)

The usage would then be:

string someData = this.Parent.GetData("someProperty", string.Empty);
Slace
A: 

It is possible to access the parent from the child control via ((ParentType)Me.Parent). This is not recommended. There is no way to know that the control would not be used on another page/control. The compiler would not catch this, this cast would cause an exception at runtime.

The best way to handle this would be for the parent to provide any information that the child control needs(create public properties or methods on the controls). This could even mean that the parent control provides a strongly typed reference of itself to the child control (possibly via an interface). This way the compiler ensures that you would not have a case where the child control was assuming a parent of the wrong type.

Jim Petkus
A: 

You could use the this.Parent property of the child control, but if you are looking for a more proper OO solution you wouldn't. Allowing the child to know anything about the parent ends up binding them in some fashion and limits reuse. In most cases this is only of interest in theory and if you are banging out some quick one-off site you can violate it as needs must. But the more proper way is to use event based communications.

ongle
A: 

Thanks for the replies.

I will consider Reflection. However, I have heard that it has a performance bottleneck.

Jim - you say:

~~

The best way to handle this would be for the parent to provide any information that the child control needs(create public properties or methods on the controls). This could even mean that the parent control provides a strongly typed reference of itself to the child control (possibly via an interface). This way the compiler ensures that you would not have a case where the child control was assuming a parent of the wrong type.

~~

In my situation, both the parent and the child(ren) implement the same interface. Is this bad design? If I add a property of a parent reference in the interface, would it work considering that the parent implements the same interface as well?

A: 
Pierre