2009-03-30 15 views
11

Tengo un control de usuario principal con una etiqueta. En el OnInit de los padres, cargo dinámicamente el control secundario. Desde el control de niños, tendré que establecer la etiqueta de los padres en algo.Acceso al control principal desde el control secundario: ASP.NET C#

El uso de la propiedad Parent devuelve la matriz inmediata que en realidad es un PlaceHolder en mi caso. Teóricamente, puedo realizar un bucle recursivo para obtener la referencia al control del usuario principal. ¿Estoy yendo en la dirección correcta aquí? ¿Hay una manera directa de hacer esto?

Respuesta

9

Intente obtener el NamingContainer del niño.

+0

funciona muy bien para mí –

0

Hay un método FindControl, pero no es recursivo si no recuerdo mal. Además, no se garantiza que todas las jerarquías de control existan en page_init, wait til page_load antes de acceder a los controles. Init es para crearlos.

0

Puede pasar una referencia del elemento primario al elemento secundario y exponer un método en el elemento primario para establecer la etiqueta, aunque esto acoplará los objetos muy estrechamente. De lo contrario, podría exponer una propiedad en el niño que el padre podría verificar y establecer su propia etiqueta.

0

Hay algunas maneras diferentes que podría ir ... Una de ellas sería añadir una propiedad Parent a su clase de niño ... y luego hacer:

// in the context of parent's loading of child: 
child.ParentObject = self; 

Estoy seguro de que alguien va a volver y decir que esto infringe alguna de las mejores prácticas u otra ... pero encogimiento de hombros. También podría usar eventos si quisiera mantener alguna separación.

0

Si está creando el UserControl a través del código, ¿por qué no pasar el padre fuertemente tipado al constructor?

public class MyUserControl1 : UserControl 
{ 
    public void Init(...) 
    { 
    var uc2 = new MyUserControl2(this); 
    } 
} 

public class MyUserControl2 : UserControl 
{ 
    private MyUserControl1 parentUserControl; 

    public MyUserControl2(MyUserControl1 parent) 
    { 
    this.parentUserControl = parent; 
    } 
} 

Ahora bien, esto está estrechamente relacionado y podría causarle problemas más adelante, pero para este caso podría funcionar.

0

Lo mejor es esperar hasta que page_load complete y luego buscar recursivamente en Page.Controles.

Éstos son algunos métodos de extensión que le ayudarán a accompish que:

var control = Page.GetControl(MyControlID);  

public static class ControlExtensions 
    { 
     public static IEnumerable<Control> Flatten(this ControlCollection controls) 
     { 
      List<Control> list = new List<Control>(); 
      controls.Traverse(c => list.Add(c)); 
      return list; 
     } 

     public static IEnumerable<Control> Flatten(this ControlCollection controls, Func<Control, bool> predicate) 
     { 
      List<Control> list = new List<Control>(); 
      controls.Traverse(c => { if (predicate(c)) list.Add(c); }); 
      return list; 
     } 

     public static void Traverse(this ControlCollection controls, Action<Control> action) 
     { 
      foreach (Control control in controls) 
      { 
       action(control); 
       if (control.HasControls()) 
       { 
        control.Controls.Traverse(action); 
       } 
      } 
     } 

     public static Control GetControl(this Control control, string id) 
     { 
      return control.Controls.Flatten(c => c.ID == id).SingleOrDefault(); 
     } 

     public static IEnumerable<Control> GetControls(this Control control) 
     { 
      return control.Controls.Flatten(); 
     } 

     public static IEnumerable<Control> GetControls(this Control control, Func<Control, bool> predicate) 
     { 
      return control.Controls.Flatten(predicate); 
     } 
    } 
4

O usted podría repetir por los padres hasta que encuentre el control deseado, por ejemplo, con un método de extensión.

public static Control GetParentOfType(this Control childControl, 
            Type parentType) 
    { 
     Control parent = childControl.Parent; 
     while(parent.GetType() != parentType) 
     { 
      parent = parent.Parent; 
     } 
     if(parent.GetType() == parentType) 
      return parent; 

    throw new Exception("No control of expected type was found"); 
    } 

Más detalles sobre este método aquí: http://www.teebot.be/2009/08/extension-method-to-get-controls-parent.html

+2

Una versión genérica de este método se puede encontrar aquí ... http: //www.extensionmethod.net/csharp/control/findparent – Stuart

1

Para mí la forma correcta de hacer esto es mediante la exposición de un método Add en el control. Ahora, si necesita actualizar una etiqueta fuera de ella, exponga un evento, algo así como OnCollectionChanged (...) y suscríbase desde el control que deberá mostrar información sobre la colección.

De esta manera cada control hace su parte y todas las estancias SOLID

1

@Rex M tiene una solución buena y fácil para esto y simplemente se expanda en la imagen para el uso:

se utiliza este fragmento de código desde dentro del control de usuario niño a la propiedad controlar el acceso de usuarios principal:

((MyParentUserControlTypeName)NamingContainer).Property1 = "Hello"; 
Cuestiones relacionadas