webforms - ASP.NET Web Forms(4.5) Enlace de modelo fuertemente tipado-DropDownList en InsertItemTemplate of ListView
model-binding strong-typing (1)
Nota: Esta es la vinculación del modelo de formularios web ASP.NET en .NET 4.5 y NO MVC.
Estoy utilizando las nuevas características de Encuadernación de modelos fuertemente tipados de ASP.NET Web Forms (4.5) para producir una lista de elementos que se pueden editar. Esto funciona bien para ver la lista inicial, editar un elemento y eliminar un elemento. Sin embargo, tengo un problema con la inserción de un nuevo artículo.
Específicamente, dentro de EditItemTemplate y InsertItemTemplate tengo una DropDownList (bueno, en realidad es un control personalizado derivado de DropDownList, pero a los efectos de esta pregunta es una DropDownList). El control se define dentro del marcado de la siguiente manera ...
<agp:ClientStatusDropDownList ID="ClientStatusID" runat="server"
SelectedValue="<%#: BindItem.ClientStatusID %>" />
Dentro de EditItemTemplate, esto está bien, sin embargo dentro de InsertItemTemplate esto genera un error al ejecutar la página: métodos de enlace de datos como Eval (), XPath () y Bind () solo pueden usarse en el contexto de un control de datos.
Como tal, SelectedValue="<%#: BindItem.ClientStatusID %>"
la sección SelectedValue="<%#: BindItem.ClientStatusID %>"
de InsertItemTemplate y lo intenté de nuevo. Esta vez, no hay ningún mensaje de error, sin embargo, cuando se llama a ListView.InsertMethod
, la propiedad ClientStatusID en el modelo no se establece en el valor de DropDownList (mientras que el resto de las propiedades se establecen correctamente).
El ListView.InsertMethod:
public void ListView_InsertMethod(int ID) {
Model model = this.DbContext.Models.Create();
if (this.TryUpdateModel(model)) {
this.DbContext.SaveChanges();
this.ListView.DataBind();
}
}
La clase de modelo:
public class Model{
public Int32 ID { get; set; }
public String Description { get; set; }
public Boolean IsScheduleFollowUp { get; set; }
public Nullable<Int32> ClientStatusID { get; set; }
}
The EditItemTemplate:
<EditItemTemplate>
<tr>
<td>
<asp:TextBox ID="Description" runat="server" Text="<%#: BindItem.Description %>" />
</td>
<td>
<asp:CheckBox ID="IsScheduleFollowUp" runat="server" Checked="<%# BindItem.IsScheduleFollowUp %>" />
</td>
<td>
<agp:ClientStatusDropDownList ID="ClientStatusID" runat="server" SelectedValue="<%#: BindItem.ClientStatusID %>" />
</td>
<td>
<asp:Button ID="Update" runat="server" ClientIDMode="Static" CommandName="Update" Text="Update" />
<asp:Button ID="Cancel" runat="server" ClientIDMode="Static" CommandName="Cancel" Text="Cancel" />
</td>
</tr>
</EditItemTemplate>
InsertItemTemplate:
<InsertItemTemplate>
<tr>
<td>
<asp:TextBox ID="Description" runat="server" Text="<%#: BindItem.Description %>" />
</td>
<td>
<asp:CheckBox ID="IsScheduleFollowUp" runat="server" Checked="<%# BindItem.IsScheduleFollowUp %>" />
</td>
<td>
<agp:ClientStatusDropDownList ID="ClientStatusID" runat="server" />
</td>
<td>
<asp:Button ID="Insert" runat="server" ClientIDMode="Static" CommandName="Insert" Text="Add" />
</td>
</tr>
</InsertItemTemplate>
Originalmente pensé que era la ID del control que se utilizó para determinar la propiedad en el modelo en el que se pasaría el valor (es decir, cuando el TextBox se llamaba "Descripción", el valor se pasaba a la "Descripción" propiedad del modelo). Claramente, este no es el caso y, en cambio, está controlado por "<% # BindItem.Description%>", sin embargo, como puede ver en el resto de esta pregunta, no puedo usar esta sintaxis en "InsertItemTemplate". No puedo creer que DropDownList no sea compatible con este escenario, pero no puedo encontrar ningún ejemplo de DropDownList que se use con los enlaces del modelo 4.5 con Google o Bing (de hecho, hay muy pocos ejemplos del nuevo enlace de modelo en ASP). NET 4.5 utilizando algo que no sea un par de controles TextBox).
¿Alguien puede arrojar más luz sobre el tema (y preferiblemente decirme qué debe hacerse)?
Otras preguntas sobre SO que he visto ...
- Enlazando una DropDownList en ListView InsertItemTemplate lanzando un error
- ASP.NET ListView con marcado idéntico en EditItemTemplate y InsertItemTemplate
- Enlace SelectedValue of ASP.net DropDownList a objeto personalizado
- Enlace de datos a la lista DropDownList de ASP.NET en ListView
Todos estos utilizan los métodos de enlace de estilo anteriores y no los nuevos métodos en 4.5
Gracias.
He estado trabajando en algo similar y he podido obtener una muestra para trabajar, así que pensé en publicar lo que tengo y ver si esto te ayuda.
Aquí está el código de mi página:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="listview-databind.aspx.cs"
Inherits="test_listview_databind" Debug="true" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ListView ID="lv" runat="server" ItemType="DataModel" DataKeyNames="Id" SelectMethod="lv_GetData"
InsertItemPosition="FirstItem" InsertMethod="lv_InsertItem" UpdateMethod="lv_UpdateItem">
<LayoutTemplate>
<table>
<tr id="itemPlaceholder" runat="server"></tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Literal ID="Description" runat="server" Text="<%# Item.Description %>" />
</td>
<td>
<asp:CheckBox ID="IsScheduleFollowUp" runat="server" Checked="<%# Item.IsScheduleFollowUp %>" />
</td>
<td>
<asp:Literal ID="ClientStatusId" runat="server" />
</td>
<td>
<asp:Button ID="Edit" runat="server" ClientIDMode="Static" CommandName="Edit"
Text="Edit" />
</td>
</tr>
</ItemTemplate>
<InsertItemTemplate>
<tr>
<td>
<asp:TextBox ID="Description" runat="server" Text="<%# BindItem.Description %>" />
</td>
<td>
<asp:CheckBox ID="IsScheduleFollowUp" runat="server" Checked="<%# BindItem.IsScheduleFollowUp %>" />
</td>
<td>
<asp:DropDownList ID="ClientStatusId" runat="server" SelectedValue="<%# BindItem.ClientStatusId %>">
<asp:ListItem>1</asp:ListItem>
<asp:ListItem>2</asp:ListItem>
</asp:DropDownList>
</td>
<td>
<asp:Button ID="Insert" runat="server" ClientIDMode="Static" CommandName="Insert"
Text="Add" />
<asp:Button ID="Cancel" runat="server" ClientIDMode="Static" CommandName="Cancel"
Text="Cancel" />
</td>
</tr>
</InsertItemTemplate>
<EditItemTemplate>
<tr>
<td>
<asp:TextBox ID="Description" runat="server" Text="<%# BindItem.Description %>" />
</td>
<td>
<asp:CheckBox ID="IsScheduleFollowUp" runat="server" Checked="<%# BindItem.IsScheduleFollowUp %>" />
</td>
<td>
<asp:DropDownList ID="ClientStatusId" runat="server" SelectedValue="<%# BindItem.ClientStatusId %>">
<asp:ListItem>1</asp:ListItem>
<asp:ListItem>2</asp:ListItem>
</asp:DropDownList>
</td>
<td>
<asp:Button ID="Update" runat="server" ClientIDMode="Static" CommandName="Update"
Text="Update" />
<asp:Button ID="Cancel" runat="server" ClientIDMode="Static" CommandName="Cancel"
Text="Cancel" />
</td>
</tr>
</EditItemTemplate>
</asp:ListView>
</form>
</body>
</html>
Y mi código detrás:
using System.Collections.Generic;
using System.Linq;
public partial class test_listview_databind : System.Web.UI.Page
{
public IQueryable<DataModel> lv_GetData()
{
var l = new List<DataModel>();
l.Add(new DataModel() { Id = 1, Description = "Test 1", IsScheduleFollowUp = true, ClientStatusId = 1 });
l.Add(new DataModel() { Id = 2, Description = "Test 2", IsScheduleFollowUp = false, ClientStatusId = 2 });
return l.AsQueryable();
}
public void lv_InsertItem()
{
var item = new DataModel();
TryUpdateModel(item);
if (ModelState.IsValid)
{
Response.Write(item.ClientStatusId);
}
}
}
No publicaste toda tu muestra de ListView, así que estoy adivinando cómo podrías configurarla. Por favor, hágame saber si esto ayuda y si / cómo esto funciona para usted, ya que su código parece viable y tengo curiosidad sobre lo que está causando su problema.