none
Mantener entradas de usuario cuándo se recarga la página RRS feed

  • Pregunta

  • Hola a todos.

    Estoy haciendo una aplicación en ASP.net.

    El comportamiento que necesito es el siguiente:

    Un campo de texto y un botón "Añadir entrada", cuándo se clica ese botón, aparece un nuevo campo de texto, y así sucesivamente. Pues bien, ese comportamiento lo tengo implementado:


    <asp:ListView ID="ListItems" class="block" SortExpression="DataType" ItemStyle-Wrap="false"  runat="server">
        <ItemTemplate  >
            <table>
                <tr>
                    <asp:TextBox ID="Name" runat="server" class="inline" Text='<%# Eval("text") %>'></asp:TextBox>
    
                </tr>
            </table>
        </ItemTemplate>
    </asp:ListView>


    protected void AddItemClick(object sender, EventArgs e)
    {
        List<UserEntry> ue;
        if (ViewState["items"] == null)
        {
            ue = new List<UserEntry>();
        }
        else
        {
            ue = (List<UserEntry>)ViewState["items"];
        }
        ue.Add(new UserEntry());
        ViewState["items"] = ue;
        ListItems.DataSource = ue;
        ListItems.DataBind();
    }


    El problema es que, cuándo le doy al botón "Add Entry", el texto que se introdujo a mano en el TextBox desaparece.


    Cómo puedo añadir una nueva entrada pero manteniendo la información introducida por el usuario  en su correspondientet TextBox?

    Muchas gracias de antemano.

    viernes, 6 de julio de 2018 22:17

Todas las respuestas

  • Lo primero que debe hacer en el evento Click es obtener el dato que se ha digitado.

    ListViewDataItem di = (ListViewDataItem)ListItems.Items[ListItems.Count - 1];
    TextBox tb = (TextBox)di.FindControl("Name");
    string newValue = tb.Text;

    Ahora puede recuperar de ViewState su colección de objetos UserEntry, ubicar el último elemento de la lista (que está en blanco pues representaba la última casilla de texto y dicha casilla es la que siempre está en blanco para nuevos items) y guardar el valor obtenido de la casilla de texto en la propiedad text del objeto UserEntry.

    ...
    UserEntry entry = ue[ue.Count - 1];
    entry.text = newValue;

    Listo.  Ahora lo único que falta es un nuevo objeto UserEntry con su propiedad text en blanco para que el ListView genere una casilla de texto vacía al final de la lista.

    ue.Add(new UserEntry());
    //Listo.  Guarde ue en el ViewState y haga el binding del ListView.
    ...

    Pienso que eso debería funcionar.


    Jose R. MCP
    My GIT Repositories | Mis Repositorios GIT

    sábado, 7 de julio de 2018 6:02
    Moderador
  • Muchas gracias por la respuesta.

    He implementado tus recomendaciones y me sigue pasando lo mismo.

    ListViewDataItem di = (ListViewDataItem)ListItems.Items[ListItems.Count - 1]; TextBox tb = (TextBox)di.FindControl("Name"); string newValue = tb.Text; //Se pone en blanco

    string newValue = "Prueba" //Aparece en el textBox

    Sin embargo, si en el evento pongo una variable de prueba, ésta aparece en el TextBox. Puede ser que el problema sea a la hora de obtener el textBox?

    sábado, 7 de julio de 2018 7:34
  • Verifique que la propiedad EnableViewState del ListView esté en true.

    Jose R. MCP
    My GIT Repositories | Mis Repositorios GIT

    sábado, 7 de julio de 2018 7:38
    Moderador
  • No estaba a true, la acabo de poner y me sigue pasando lo mismo.
    sábado, 7 de julio de 2018 8:08
  • Código actual del AddItemClick:

    protectedvoid AddItem_Click(object sender, EventArgs e)     {         List<UserEntry> ue = (List<UserEntry>)ViewState["items"];         ListViewDataItem di = (ListViewDataItem)ListItems.Items[ListItems.Count - 1];         TextBox tb = (TextBox)di.FindControl("Name");         string newValue = tb.Text; //Se pone en blanco         ue[0].Text= newValue;         ue.Add(new UserEntry());         ViewState["items"] = ue;         ListItems.DataSource = ue;         ListItems.DataBind();     }

    Y en la parte vista:

    <asp:ListView ID="ListItems" EnableViewState="true" class="block" SortExpression="DataType" ItemStyle-Wrap="false" OnItemDataBound="ListView_ItemDataBound" runat="server">
        <ItemTemplate  >
            <table>
                <tr>
                    <asp:TextBox ID="Name" runat="server" class="inline" Text='<%# Eval("Text"%>'></asp:TextBox>   
                </tr>
            </table>
        </ItemTemplate>
    </asp:ListView>

     

    sábado, 7 de julio de 2018 9:35
  • Poner ue[0] es malo.  No es el primer item.  Es el último.  Es ue[ue.Count - 1].Text = newValue.  Así se lo puse yo originalmente.

    La propiedad EnabledViewState tiene que estar en true para todos los contenedores del ListView.  Si ListView está dentro de un Panel, por ejemplo, el Panel tiene que tener esta propiedad en true, y a su vez el contenedor que contiene el panel, etc. etc. hasta llegar al objeto Page, que también debe tener esta propiedad en true.  Si algún padre en la cadena lo desactiva (false), entonces los hijos de ahí en adelante lo tendrán desactivado también.


    Jose R. MCP
    My GIT Repositories | Mis Repositorios GIT

    sábado, 7 de julio de 2018 18:13
    Moderador