2013-02-18 4 views
8

Примечание. Это привязка модели веб-форм ASP.NET в .NET 4.5 и NOT MVC.ASP.NET Web Forms (4.5) Сильно типизированная привязка модели - DropDownList в InsertItemTemplate ListView

Я использую новые сильно привязанные функции привязки модели ASP.NET Web Forms (4.5) для создания списка элементов, которые можно редактировать. Это отлично работает для просмотра исходного списка, редактирования элемента и удаления элемента. Однако у меня возникла проблема с вставкой нового элемента.

В частности, в моем EditItemTemplate и InsertItemTemplate у меня есть DropDownList (ну, на самом деле это настраиваемый элемент управления, полученный из DropDownList, но для целей этого вопроса это DropDownList). Контроль определяется в пределах разметки следующим образом ...

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

В EditItemTemplate, это хорошо, однако в рамках этого InsertItemTemplate генерирует сообщение об ошибке при запуске страницы: методы Databinding, такие как Eval(), XPath (), а Bind() может использоваться только в контексте управления базой данных.

Как таковой, я удалил раздел SelectedValue="<%#: BindItem.ClientStatusID %>" из InsertItemTemplate и попытался снова. На этот раз нет сообщения об ошибке, однако, когда вызывается ListView.InsertMethod, свойство ClientStatusID в модели не задано значением DropDownList (тогда как остальные свойства заданы правильно).

ListView.InsertMethod:

public void ListView_InsertMethod(int ID) { 

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

} 

Класс 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> 

Первоначально я думал, что это идентификатор элемента управления, который использовался для определения свойства на модели, которое значение будет передано (т. где TextBox был вызван «Описание», значение будет передано в свойство «Описание» модели). Ясно, что это не так, и вместо этого он управляется «<% # BindItem.Description%>», однако, как вы можете видеть из остальной части этого вопроса, я не могу использовать этот синтаксис в «InsertItemTemplate». Я не могу поверить, что DropDownList не поддерживается в этом сценарии, но я не могу найти примеры DropDownList, которые используются с привязками к модели 4.5 с помощью Google или Bing (на самом деле, есть очень мало примеров привязки новой модели в ASP. NET 4.5, используя что-либо, кроме нескольких элементов управления TextBox).

Может ли кто-нибудь пролить свет на проблему (и, желательно, сказать мне, что нужно сделать)?

Другие вопросы о том, как я смотрел ...

Все они используют старый стиль связывания методов, а не новые методы в 4,5

Спасибо.

+0

Только для справки; Я также попытался привязать к альтернативной модели, где ClientStatusID не имеет значения NULL (это код, а не разметка). Никакой разницы, свойство все еще не установлено. Это (на мой взгляд) исключает любые возможные проблемы в свойствах, которые могут быть обнуляемы. –

ответ

6

Я работал над чем-то похожим и смог получить образец для работы, поэтому я решил, что опубликую то, что у меня есть, и посмотрим, поможет ли это вам.

Вот мой код страницы:

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

И мой код позади:

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

Вы не отправлял весь образец ListView, поэтому я принимаю предположение относительно того, как вы могли бы настройте его. Пожалуйста, дайте мне знать, если это поможет, и если/как это работает для вас, так как ваш код выглядит работоспособным, и мне любопытно, что вызывает вашу проблему.

+2

Интересно; Мне не удалось использовать синтаксис BindItem в моем InsertItemTemplate, но вы могли. Это заставило меня задуматься и пересмотреть мою реализацию ClientStatusDropDownList, где я нашел проблему - я вызывал DataBind во время OnLoad (где! PostBack), и поэтому контекст привязки для BindItem был недействительным. Удаление вызова DataBind устранило проблему. Хотя вы не дали ответа (так как я не предоставил достаточно первого), вы помогли мне решить его, поэтому я считаю вас правильными. –

+0

Только для записи: ClientStatusDropDownList - это реализация DropDownList с привязкой жестко закодированной (полученной из DropDownList), чтобы я мог просто отбросить ее на странице и не беспокоиться о проводке. –

 Смежные вопросы

  • Нет связанных вопросов^_^