Pregunta

Tengo un ListView como este

<asp:ListView ID="ListView1" runat="server">
   <EmptyDataTemplate>
      <asp:Literal ID="Literal1" runat="server" text="some text"/>
   </EmptyDataTemplate>
   ...
</asp:ListView>

En Page_Load () tengo lo siguiente:

Literal x = (Literal)ListView1.FindControl("Literal1");
x.Text = "other text";

pero x devuelve null . Me gustaría cambiar el texto del control Literal pero no tengo idea de cómo hacerlo.

¿Fue útil?

Solución

Creo que, a menos que llame al método DataBind de su ListView en algún lugar del código que se encuentra detrás, ListView nunca intentará enlazar los datos. Entonces nada se procesará e incluso el control Literal no se creará.

En su evento Page_Load intente algo como:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        //ListView1.DataSource = ...
        ListView1.DataBind();

        //if you know its empty empty data template is the first parent control
        // aka Controls[0]
        Control c = ListView1.Controls[0].FindControl("Literal1");
        if (c != null)
        {
            //this will atleast tell you  if the control exists or not
        }    
    }
}

Otros consejos

Puede usar lo siguiente:

 protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
        {
            if (e.Item.ItemType == ListViewItemType.EmptyItem)
            {
                 Control c = e.Item.FindControl("Literal1");
                if (c != null)
                {
                    //this will atleast tell you  if the control exists or not
                }
            }
        }

No es específicamente lo que pediste, pero otra forma de hacer ese tipo de cosas es la siguiente:

<EmptyDataTemplate>
  <%= Foobar() %>
</EmptyDataTemplate>

donde Foobar se define en el código de su página detrás del archivo

public partial class MyClass : System.Web.UI.Page
{
...
    public string Foobar()
    {
         return "whatever";
    }
}

Un enfoque alternativo ...

<asp:ListView ID="ListView1" runat="server">
   <EmptyDataTemplate>
      <asp:Literal ID="Literal1" runat="server" text="some text" OnInit="Literal1_Init" />
   </EmptyDataTemplate>
   ...
</asp:ListView>

En el código subyacente ...

protected void Literal1_Init(object sender, EventArgs e)
{
    (sender as Literal).Text = "Some other text";
}
 Protected Sub ListView1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewItemEventArgs) Handles ListView1.ItemDataBound
    Dim searchValue As String = Replace(Request.QueryString("s"), "", "'")
    Dim searchLiteral2 As Literal = CType(ListView1.FindControl("Literal2"), Literal)
    searchLiteral2.Text = "''" & searchValue & "''"
End Sub

...

Respondiendo la pregunta de Broam " ¿Hay alguna forma de hacer esto en el método de enlace de datos? Prefiero no codificar "controles" [0] " ya que es descuidado "

protected void ListView1_DataBound(object sender, EventArgs e)
{
    ListView mylist = ((ListView)sender);
    ListViewItem lvi = null;
    if (mylist.Controls.Count == 1)
        lvi = mylist.Controls[0] as ListViewItem;

    if (lvi == null || lvi.ItemType != ListViewItemType.EmptyItem)
        return;

    Literal literal1 = (Literal)lvi.FindControl("Literal1");
    if (literal1 != null)
        literal1.Text = "No items to display";
}

Desafortunadamente, no he encontrado una manera de no usar los Controles [0].

En los eventos de elementos habituales (ItemDataBound o ItemCreate), puede usar e.Item de ListViewItemEventArgs para obtener ListViewItem. En el evento DataBound, solo hay un EventArgs genérico.

Y encima de eso, parece que ((Control) remitente) .FindControl (" Literal1 ") tampoco funciona (busque el control en la vista de lista en la parte superior del árbol), de ahí el uso de Controles [0] .FindControl (...) (encuentra el control del elemento listview).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top