asp.net controls webforms tag-property

Vb6 Propiedad "Tag" equivalente en ASP.Net?



controls webforms (7)

Estoy buscando ideas y opiniones aquí, no una "respuesta real", supongo ...

En los viejos días VB6, había una propiedad llamada "Etiqueta" en todos los controles, que era una forma útil de almacenar información personalizada relacionada con un control. Cada control individual lo tenía, y todo era dicha ...

Ahora, en .Net (al menos para WebForms), ya no está allí ...

¿Alguien tiene un buen reemplazo para eso?

Encuentro este problema muy a menudo, donde tengo diferentes funciones que se ejecutan en diferentes momentos en el ciclo de vida, y hacen cosas con mis controles, y quiero mantenerlos separados como están, pero uno debe pasar información a la otra sobre controles específicos.

Puedo pensar en un millón de alternativas (comenzando con un diccionario de nivel de módulo, obviamente), pero ninguna tan limpia como la buena etiqueta.

(NOTA: Sé que puedo subclasificar TODOS los controles y usar mi versión. Preferiría no hacerlo)

¿Alguna sugerencia? ¿Cómo resuelves esto normalmente? ¿Alguna idea sobre por qué eliminaron este yo el primer lugar?

EDITAR: estoy buscando algo Intra-Request, no Inter-Request. No necesito esta información para seguir allí en un PostBack. Esto es entre los métodos _Load y _PreRender, por ejemplo.

EDIT2: SÍ, conozco mi ASp.Net y sé la diferencia entre el escritorio y la web, ¡muchachos !. Solo intento usar la abstracción que .Net me da al máximo. Entiendo las concesiones, créanme, y respondan asumiendo que sí.


La propiedad Tag siempre fue una cosa rara como una verruga que era útil como algo fuera de lo cual podías colgar cualquier información que quisieras. Pero no estaba fuertemente tipado y realmente no lo hacía para un diseño coherente. La propiedad en sí misma colgaba del control como una extraña perilla. Lo mantuvieron en WinForms para facilitar el porteo del código desde VB6. La nueva clase de Control WPF no tiene una Tag .

Con .NET tiene una orientación de objeto completa y un polimorfismo de tipo adecuado, por lo que puede escribir con fuerza cualquier información adicional que desee asociar con un código, ya sea en una subclase o en un Dictionary<Control,TValue> .

Si está en una sola solicitud de Page y desea una solución general, un diccionario en la página en sí para cada tipo de valor (por ejemplo, Dictionary<Control,string> y Dictionary<Control,BusinessObject> ) debería ser exactamente lo que necesita.


No estoy seguro de qué hizo la propiedad de etiqueta en VB6, pero tal vez esté buscando la propiedad Attributes de los controles web:

MyImgCtrl.Attributes["myCustomTagAttribute"] = "myVal";


Preguntaste sobre ASP.Net, pero vb6 era un lenguaje de escritorio, y también lo eran sus controles ''etiquetados''. El VBScript utilizado para el asp clásico no tenía realmente un concepto de control.

Ahora en .Net, para controles de escritorio puede usar herencia, que es mucho más poderosa que la antigua propiedad Tag de todos modos. La herencia se aplica a los controles web también, aunque debe tener cuidado al usarla para mantener el estado.


Puede agregar atributos a algunos controles, pero eso parece agregar un poco de HTML desagradable alrededor del control renderizado, algo así como <div attrName="attrValue"> ... (aunque podría ser un intervalo)


También puede usar el patrón compuesto en lugar de usar inheritence:

public class TaggedControl<TControl, TTag> : Control where TControl : Control, new() { public TaggedControl() {this.Control= new TControl();} public TControl Control {get; private set;} public TTag Tag {get; set;} protected override void CreateChildControls(){Controls.Add(Control);} } var textBox = new TaggedControl<TextBox, string>(); textBox.Tag = "Test"; label.Text = textBox.Tag;


No, no hay un equivalente directo, pero si está usando v3.5 del Framework, puede agregar esta funcionalidad bastante fácilmente usando un método de extensión. Por ejemplo:

Imports System.Runtime.CompilerServices Public Module Extensions <Extension()> _ Public Sub SetTag(ByVal ctl As Control, ByVal tagValue As String) If SessionTagDictionary.ContainsKey(TagName(ctl)) Then SessionTagDictionary(TagName(ctl)) = tagValue Else SessionTagDictionary.Add(TagName(ctl), tagValue) End If End Sub <Extension()> _ Public Function GetTag(ByVal ctl As Control) As String If SessionTagDictionary.ContainsKey(TagName(ctl)) Then Return SessionTagDictionary(TagName(ctl)) Else Return String.Empty End If End Function Private Function TagName(ByVal ctl As Control) As String Return ctl.Page.ClientID & "." & ctl.ClientID End Function Private Function SessionTagDictionary() As Dictionary(Of String, String) If HttpContext.Current.Session("TagDictionary") Is Nothing Then SessionTagDictionary = New Dictionary(Of String, String) HttpContext.Current.Session("TagDictionary") = SessionTagDictionary Else SessionTagDictionary = DirectCast(HttpContext.Current.Session("TagDictionary"), _ Dictionary(Of String, String)) End If End Function End Module

Luego, en sus páginas ASP.NET, primero ponga sus extensiones dentro del alcance, por ejemplo:

Imports WebApplication1.Extensions

... y luego usa tus controles como desees:

TextBox1.SetTag("Test") Label1.Text = TextBox1.GetTag

EDITACIÓN MÁS TARDE: y si realmente, realmente no desea almacenar sus etiquetas en el objeto Session, es posible rellenarlas en su Viewstate. Por supuesto, esto significará que sus etiquetas estarán expuestas en el marcado de página enviado al usuario (aunque en forma ofuscada), y, desafortunadamente, que se requiere algún reflejo-fu, ya que la propiedad ViewState de una página está marcada como ''protegida '' por alguna razón.

Por lo tanto, este código debería considerarse solo para fines de entretenimiento, a menos que realmente desee levantar las cejas durante las revisiones del código:

<Extension()> _ Public Sub SetTag(ByVal ctl As Control, ByVal tagValue As String) ViewState.Add(ctl.ID & "_Tag", tagValue) End Sub <Extension()> _ Public Function GetTag(ByVal ctl As Control) As String Return ViewState(ctl.ID & "_Tag") End Function Private Function ViewState() As Web.UI.StateBag Return HttpContext.Current.Handler.GetType.InvokeMember("ViewState", _ Reflection.BindingFlags.GetProperty + _ Reflection.BindingFlags.Instance + _ Reflection.BindingFlags.NonPublic, _ Nothing, HttpContext.Current.CurrentHandler, Nothing) End Function

EDICIÓN FINAL (lo prometo ...). Y aquí hay una manera de deshacerse de la reflexión: primero, cree una nueva clase para exponer la propiedad ViewState con un nivel de protección utilizable, luego cambie sus clases de código subyacente (.aspx.vb) para heredar eso en lugar de Web.UI. Página, por ejemplo:

Public Class PageEx Inherits System.Web.UI.Page Friend ReadOnly Property ViewStateEx() As Web.UI.StateBag Get Return MyBase.ViewState End Get End Property End Class

Ahora, en su módulo de extensiones, puede acceder a esta propiedad recién definida como:

Private Function ViewState() As Web.UI.StateBag Return DirectCast(HttpContext.Current.Handler, PageEx).ViewStateEx End Function

Todavía es un truco, pero mucho más aceptable que usar la reflexión ...


Puedes usar asp: controles ocultos para almacenar datos entre publicaciones. Como dice will, no tiene sentido tener una propiedad de etiqueta si pierdes su valor.