2013-02-18 63 views
8

注意:这是.NET 4.5和ASP.NET MVC中的ASP.NET Web窗体模型绑定。ASP.NET Web窗体(4.5)强类型模型绑定 - ListView的InsertItemTemplate中的DropDownList

我正在使用ASP.NET Web窗体(4.5)的新强类型模型绑定功能来生成可以编辑的项目列表。这对于查看初始列表,编辑项目和删除项目工作正常。但是,我插入一个新项目时遇到问题。

具体来说,在我的EditItemTemplate和InsertItemTemplate中,我有一个DropDownList(嗯,实际上它是从DropDownList派生的一个自定义控件,但为了这个问题的目的,它是一个DropDownList)。控制是如下的标记内定义...

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

内EditItemTemplate中,这是然而,这在运行页面生成错误InsertTemplate则内细:数据绑定方法如eval()函数,XPath的( )和Bind()只能用于数据绑定控件的上下文中。

因此,我从InsertItemTemplate中删除了部分SelectedValue="<%#: BindItem.ClientStatusID %>",然后再次尝试。这次没有错误消息,但是当调用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> 

InsertTemplate则:

<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,但我找不到任何与使用Google或Bing的4.5模型绑定一起使用的DropDownList的示例(事实上,ASP中的新模型绑定的例子非常少。 NET 4.5使用除了几个TextBox控件以外的任何东西)。

有没有人可以进一步阐明这个问题(并且最好告诉我需要做什么)?

关于我所看到的其他问题......

所有这些使用旧样式的绑定方法,而不是新的方法在4.5

感谢。

+0

仅供参考;我也尝试绑定到ClientStatusID不可为空的替代模型(这是代码隐藏,而不是标记)。没有区别,财产仍然没有设置。这(在我看来)排除了可能为空的任何潜在问题。 – 2013-02-18 12:14:06

回答

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

有趣;我无法在我的InsertItemTemplate中使用BindItem语法,但你可以。这让我想到并重新审视了ClientStatusDropDownList的实现,我发现问题 - 我在OnLoad(where!PostBack)期间调用了DataBind,这就是为什么BindItem的绑定上下文无效。删除DataBind调用已解决该问题。虽然你没有提供答案(因为我没有提供足够的答案),但你已经帮助我解决了问题,所以我将你标为正确答案。 – 2013-02-25 17:48:55

+0

只是为了记录:ClientStatusDropDownList是一个DropDownList的实现,其绑定的硬编码(派生自DropDownList),这样我就可以简单地在页面上放一个,而不必担心布线。 – 2013-02-25 17:51:57