¡esta es mi primera publicación! Estoy bastante desesperado, así que voy más allá de mi búsqueda en Google estándar. Creo que esta es una pregunta .NET avanzada o de nivel experto.Inserte controles dinámicos en la mitad de la colección de controles
El problema es que he creado una aplicación web .NET que necesita poder insertar controles de usuario dinámicamente en el medio de una lista. Estoy bastante cómodo con los controles dinámicos, siempre y cuando solo necesiten agregarse al final de la lista (es decir, estoy familiarizado con artículos como este: http://msdn.microsoft.com/en-us/library/ms972976.aspx). Sin embargo, si necesito agregar un UserControl al frente de una colección de controles o en algún lugar en el medio, estoy bastante perdido ya que el UniqueID del control se descarta.
Como ejemplo simplificado, digamos que tengo un Panel al que agrego una lista de UserControls llamada MyControl.ascx. También tengo algún evento que pueda ser activado en la página para que se necesite insertar dinámicamente un MyControl.ascx en el índice especificado de la colección Controls del panel. También tengo uno o más eventos en MyControl.ascx a los que debo suscribirme. Esto significa que los controles deben cargarse ANTES de que los eventos en estos controles se disparen o de lo contrario no se dispararán. Si usted no sabe a lo que me refiero entonces ya sea redactado la pregunta mal o esta pregunta podría ser demasiado difícil para ti :)
A continuación se muestra un poco de C# pseudocódigo para demostrar el problema. El problema es que el método Controls.AddAt (índice, control) NO ajusta los valores UniqueID de los controles en consecuencia. Por ejemplo, considere los siguientes controles en una colección de controles:
Si estoy escribiendo código que dependa directamente de UniqueID o no, .NET usa indirectamente UniqueID para vincular los eventos que se activaron en la devolución de datos anterior. con los controles cargados en la nueva devolución de datos. Tomando mi ejemplo anterior de:
en posición inicial Page Load (Page.IsPostback == false)
<table>
<tr>
<td width='100'>Control index</td>
<td width='75'>UniqueID</td>
<td>Value</td>
</tr>
<tr>
<td>0</td>
<td>ctl00</td>
<td>value1</td>
</tr>
<tr>
<td>1</td>
<td>ctl01</td>
<td>value2</td>
</tr>
<tr>
<td>2</td>
<td>ctl02</td>
<td>value3</td>
</tr>
</table>
Después de una devolución de datos (Page.IsPostback == false
) de algún otro control que quiere insertar el control en el índice 0:
si hago un Controls.AddAt(0, newControl)
entonces la colección Controls es como la siguiente:
<table>
<tr>
<td width='100'>Control index</td>
<td width='75'>UniqueID</td>
<td>Value</td>
</tr>
<tr>
<td>0</td>
<td>ctl03</td>
<td>value0 <== the controls' unique IDs do not shift!</td>
</tr>
<tr>
<td>1</td>
<td>ctl00</td>
<td>value1</td>
</tr>
<tr>
<td>2</td>
<td>ctl01</td>
<td>value2</td>
</tr>
<tr>
<td>3</td>
<td>ctl02</td>
<td>value3</td>
</tr>
</table>
Así que si yo fuera a hacer clic en un LinkButton en el control con Value == value0 y UniqueID == ctl03, los controles se ordenarían como los siguientes en post-back y los UniqueID no estarían en el orden que deseo. Esto hará que el evento click para insertarse en el control equivocado:
<table>
<tr>
<td width='100'>Control index</td>
<td width='75'>UniqueID</td>
<td>Value</td>
</tr>
<tr>
<td>0</td>
<td>ctl00</td>
<td>value0 <== the control i wanted to throw the event</td>
</tr>
<tr>
<td>1</td>
<td>ctl01</td>
<td>value1</td>
</tr>
<tr>
<td>2</td>
<td>ctl02</td>
<td>value2</td>
</tr>
<tr>
<td>3</td>
<td>ctl03</td>
<td>value3 <== the actual control to which the event is attached</td>
</tr>
</table>
Si yo no tuviera que manejar eventos de estos controles dinámicos esto probablemente no sería un problema. Aquí está mi código:
// on init i just need to pull the records from the DB, turn them
// into a MyControl.ascx, and then add them to my panel
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
// get my List<SomethingFromDB> ordered by value and iterate through,
// adding controls to the control collection
List<SomethingFromDB> myList = remoteService.GetSomeListFromTheDB();
foreach(SomethingFromDB something in List<SomethingFromDB>)
{
// load a new MyControl.ascx
MyControl myControl = (MyControl)LoadControl("~/Controls/MyControl .ascx");
// populate the values of myControl with the "something"
this.populateMyControl(something);
// dynamically add the control to my panel
this.myPanel.Add(myControl);
// subscribe to event
myControl.SomeArbitraryEvent += new EventHandler(MyArbitraryHandler);
}
// This event gets fired by a magical control on the page and passes a
// new SomethingFromDB which needs to be inserted into the DB and then
// dynamically inserted into the Controls collection at the specified index
private void SomeOtherControl_ClickInsert(object sender, MyControlEventArgs e)
{
// insert this record into the DB
remoteService.InsertIntoDB(e.SomethingFromDB);
// dynamically load this control
MyControl myControl = (MyControl)LoadControl("~/Controls/MyControl .ascx");
// get the index into which we will be inserting this control
int index = e.NewIndex;
//dynamically add the control to my panel at the specified index.
// THIS DOES NOT ADJUST THE UNIQUEID VALUES ACCORDINGLY
// AND IS THE SOURCE OF MY PROBLEM!
this.myPanel.AddAt(index, myControl);
}
Por favor ayuda. Este me está matando. Si necesita más información o tiene preguntas, hágamelo saber y estaremos encantados de brindarle más información. ¡GRANDEMENTE aprecio tu ayuda!
Ahora, no va por el camino correcto, está explicando su problema en lugar de explicar lo que quiere lograr. Hay una diferencia en eso que hace que sea difícil sugerir mejores formas (que a veces son las formas correctas) de abordar un problema en particular. Edita tu pregunta! –