2013-02-18 19 views
8

Uwaga: To jest ASP.NET Web Forms Model Binding w .NET 4.5 i NOT MVC.ASP.NET Web Forms (4.5) Silnie wpisane wiązanie modelu - DropDownList w InsertItemTemplate of ListView

Korzystam z nowych funkcji silnie typowego wiązania modelu ASP.NET Web Forms (4.5), aby utworzyć listę elementów, które można edytować. Działa to dobrze, gdy przeglądasz początkową listę, edytujesz element i usuwasz element. Mam jednak problem z wstawieniem nowego przedmiotu.

W szczególności, w moim EditItemTemplate i InsertItemTemplate mam DropDownList (cóż, w rzeczywistości jest to niestandardowe sterowanie pochodzące z DropDownList, ale dla celów tego pytania jest to DropDownList). Kontrola jest zdefiniowana w znaczników w następujący sposób ...

<agp:ClientStatusDropDownList ID="ClientStatusID" runat="server" 
SelectedValue="<%#: BindItem.ClientStatusID %>" /> 

W EditItemTemplate, to jest w porządku, jednak w InsertItemTemplate to generuje błąd po uruchomieniu strony: metody wiązania z danymi takimi jak eval(), (XPath), a funkcja Bind() może być używana tylko w kontekście kontroli danych.

Jako takie, usunąłem sekcję SelectedValue="<%#: BindItem.ClientStatusID %>" z InsertItemTemplate i spróbowałem ponownie. Tym razem brak komunikatu o błędzie, jednak po wywołaniu ListView.InsertMethod właściwość ClientStatusID w modelu nie jest ustawiona na wartość DropDownList (podczas gdy pozostałe właściwości są ustawione poprawnie).

ListView.InsertMethod:

public void ListView_InsertMethod(int ID) { 

    Model model = this.DbContext.Models.Create(); 
    if (this.TryUpdateModel(model)) { 
    this.DbContext.SaveChanges(); 
    this.ListView.DataBind(); 
    } 

} 

Klasa Model:

public class Model{ 

    public Int32 ID { get; set; } 
    public String Description { get; set; } 
    public Boolean IsScheduleFollowUp { get; set; } 
    public Nullable<Int32> ClientStatusID { get; set; } 

} 

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> 

Początkowo sądziłem, że był to identyfikator kontrolki, który został użyty do określenia właściwości modelu, do którego wartość zostanie przekazana (tj. gdzie TextBox został nazwany "Opis", wartość zostanie przekazana do właściwości "Opis" modelu). Oczywiście tak nie jest i jest on kontrolowany przez "<% # BindItem.Description%>", jednak jak widać z pozostałej części tego pytania, nie mogę użyć tej składni w "InsertItemTemplate". Nie mogę uwierzyć, że DropDownList nie jest obsługiwany w tym scenariuszu, ale nie mogę znaleźć żadnych przykładów DropDownList używanych z powiązaniami modelu 4.5 za pomocą Google lub Bing (w rzeczywistości istnieje bardzo niewiele przykładów nowego wiązania modelu w ASP. NET 4.5 za pomocą czegokolwiek innego niż kilka elementów sterujących TextBox).

Czy ktoś może rzucić więcej światła na tę kwestię (i najlepiej powiedzieć, co należy zrobić)?

Inne pytania dotyczące SO, na które patrzyłem ...

Wszystkie te metody korzystania z wiążących starym stylu, a nie nowych metod w 4,5

Dzięki.

+0

Tylko w celach informacyjnych; Próbowałem również powiązania z alternatywnym modelem, w którym ClientStatusID nie jest zerowalny (to jest kod z tyłu, a nie znaczników). Bez różnicy, nieruchomość wciąż nie jest ustawiona. To (według mnie) wyklucza wszelkie potencjalne problemy z właściwością, która jest zerowa. –

Odpowiedz

6

Pracowałem nad czymś podobnym i udało mi się uzyskać próbkę do pracy, więc pomyślałem, że opublikuję to, co mam i zobaczę, czy to ci pomoże.

Oto mój kod strony:

<%@ 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> 

A mój kod za:

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); 
     } 
    } 
} 

Nie pisać całą próbkę ListView, więc biorę się domyślać, jak to polubisz ustaw to. Daj mi znać, jeśli to pomoże i jeśli/jak to działa, ponieważ Twój kod wygląda na sprawny i jestem ciekawy, co jest przyczyną problemu.

+2

Interesujące; Nie mogłem jeszcze użyć składni BindItem w moim InsertItemTemplate. To sprawiło, że pomyślałem i wróciłem do mojej implementacji ClientStatusDropDownList, gdzie znalazłem problem - wywoływałem DataBind podczas OnLoad (gdzie! PostBack) i to dlatego kontekst wiążący dla BindItem był nieprawidłowy. Usunięcie połączenia DataBind rozwiązało problem. Chociaż nie dostarczyłeś odpowiedzi (jako że wcześniej nie dostarczyłem wystarczającej ilości), pomogłeś mi rozwiązać ten problem, więc zaznaczam Cię jako poprawną. –

+0

Po prostu dla zapisu: ClientStatusDropDownList jest implementacją DropDownList z wiążącym zakodowanym na sztywno (pochodzącym z DropDownList), tak żebym mógł po prostu upuścić jeden na stronie i nie martwić się o okablowanie. –