René Pacios

/* Overflow My Brain & More */

Compartir datos entre User Controls usando ViewState

El otro día en la oficina surgió la necesidad de pasar datos desde un control de usuario a otro que se encontraban en la misma página, y preguntaron “¿Se puede utilizar el ViewState desde el control para compartir la información entre ellos?”

La respuesta es un poco ambigua, en principio no es posible compartir datos de un control a otro usando este mecanismo, ya que el ViewState de cada control trabaja dentro del contexto de este y no dentro del contexto de la página.

Por otro lado un control de usuario, no puede representarse sin una pagina, es decir no podemos acceder a un control de usuario directamente desde el navegador, este debe estar “hospedado” en una página .aspx, teniendo en cuenta esta premisa, desde el control de usuario podremos acceder a las propiedades de la página que la alberga.

Para este ejemplo, he utilizado una clase base para las páginas de esta forma será más sencilla trabajar de forma tipada con los sitios Web dado que su modo de compilación no lo permite de forma sencilla quedando nuestro código de la siguiente forma.

//Clase Base común a todas las páginas
using System.Web.UI;
public class PageBaseClass : Page
{
    public PageBaseClass(){}
}

//Ejemplo de página
using System;

public partial class DefaultPage : PageBaseClass
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
}

Como podemos ver, hemos creado una clase base que nos va a permitir implementar comportamientos comunes para nuestras páginas, veamos como nos puede ayudar esto:

using System.Web.UI;
public class PageBaseClass : Page
{
    public StateBag PageViewStaate
    {
        get{return this.ViewState;}
    }

    public PageBaseClass(){}
}

En el código anterior podemos observar que se ha implementado una propiedad pública que nos permitirá acceder directamente al ViewState de la página instanciada. Por otro lado agregaremos el siguiente código a la página principal, que nos va a permitir ver como cambia el ViewState de la página:

using System;

public partial class DefaultPage : PageBaseClass
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (null == this.ViewState.Keys) return;
        //Mostramos los datos que contiene el ViewState de la página
        lblPageViewState.Text = string.Empty;
        foreach (string clave in ViewState.Keys)
        {
            lblPageViewState.Text += string.Format("<br/>Clave: {0} Valor {1}", clave, this.ViewState[clave]);
        }
    }
}

De acuerdo, pero no íbamos a compartir datos entre controles de usuario? Para este ejemplo implementamos el siguiente control de usuario que nos va a permitir probar nuestro ejemplo.

image

 

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl.ascx.cs" Inherits="WebUserControl" %>


<asp:RadioButtonList runat="server" ID="rdblOpciones">
    <asp:ListItem Value="UserControl">Usar  ViewState de Control de Usuario</asp:ListItem>
    <asp:ListItem Value="page">Usar ViewState de Página</asp:ListItem>
</asp:RadioButtonList>
<br/>
<asp:TextBox ID="txtDatos" runat="server"></asp:TextBox><br/>
<asp:Button ID="btnInsertar" runat="server" Text="Guarda en ViewState" OnClick="btnInsertar_Click1"  /><br/><br/>
<asp:Label Text="" ID="lblDatos" runat="server" /><br/>
<asp:Button ID="btnConsultar" runat="server" Text="Consulta ViewState" OnClick="btnConsultar_Click" />

Y ahora veamos como podemos compartir datos entre los diferentes controles de usuario utilizando para ello el ViewState 

using System;

public partial class WebUserControl : System.Web.UI.UserControl
{
    private const string _clave = "claveControl";

    protected void btnInsertar_Click1(object sender, EventArgs e)
    {
        if ("page" == rdblOpciones.SelectedValue)
        {
            ((PageBaseClass)this.Page).PageViewStaate[_clave] = txtDatos.Text;

        }
        else
        {
            ViewState[_clave] = txtDatos.Text;
        }
    }
    protected void btnConsultar_Click(object sender, EventArgs e)
    {
        if ("page" == rdblOpciones.SelectedValue)
        {
            lblDatos.Text = (string)((PageBaseClass)this.Page).PageViewStaate[_clave];
        }
        lblDatos.Text = (string)ViewState[_clave];
    }

}

He incluido un control de tipo Radio que nos permitirá seleccionar si queremos almacenar la información en el ViewState desde el control de forma tradicional o en accediendo directamente al ViewState de la página.

Para probar este ejemplo agregaremos dos controles de tipo “WebUserControl” que hemos definido anteriormente, a la página principal.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="DefaultPage" %>

<%@ Register Src="WebUserControl.ascx" TagName="WebUserControl" TagPrefix="uc1" %>
<!DOCTYPE html>
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>.:Ejemplo UCViewState:.</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <uc1:WebUserControl ID="WebUserControl1" runat="server" />
            <uc1:WebUserControl ID="WebUserControl2" runat="server" />
        </div>
        <div>
            <asp:Label Text="ViewState Pagina: " ID="lblPageViewState" runat="server" />
        </div>
    </form>
</body>

Con esto hemos visto una forma sencilla de compartir información entre dos o más controles de usuario.

Código de ejemplo: UCViewState.zip

 

Espero que os haya resultado de utilidad.

Nos leemos, René Pacios

Acerca de René

René Pacios es un apasionado de la tecnología, autodidacta, emprendedor, le encanta el desarrollo web, para moviles, aplicaciones, todo aquello que automatice tareas y haga que las máquinas trabajen para él. Es un gran fan de las tecnologías Microsoft, y le encanta estar a la última siempre que el tiempo se lo permite. Siempre quiso ser cantante, pero creo que en esta vida se va a quedar sólo en canta-mañanas

               

Agregar comentario

Loading