Note: This is ASP.NET Web Forms Model Binding in .NET 4.5 and NOT MVC.
I am using the new Strongly Typed Model Binding features of ASP.NET Web Forms (4.5) to produce a list of items that can be edited. This is working fine for viewing the initial list, editing an item and deleting an item. I am however having a problem with the insertion of a new item.
Specifically, within my EditItemTemplate and InsertItemTemplate I have a DropDownList (well, actually it is a custom control derived from DropDownList but for the purposes of this question it is a DropDownList). The control is defined within the markup as follows...
<agp:ClientStatusDropDownList ID="ClientStatusID" runat="server"
SelectedValue="<%#: BindItem.ClientStatusID %>" />
Within the EditItemTemplate, this is fine however within the InsertItemTemplate this generates an error upon running the page: Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.
As such, I removed the section SelectedValue="<%#: BindItem.ClientStatusID %>"
from the InsertItemTemplate and tried again. This time no error message, however when the ListView.InsertMethod
is called, the ClientStatusID property on the model is not set to the value of the DropDownList (whereas the rest of the properties are set correctly).
The ListView.InsertMethod:
public void ListView_InsertMethod(int ID) {
Model model = this.DbContext.Models.Create();
if (this.TryUpdateModel(model)) {
this.DbContext.SaveChanges();
this.ListView.DataBind();
}
}
The Model class:
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>
The 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>
I had originally thought that it was the ID of the control that was used to determine the property on the model that the value would be passed to (i.e. where the TextBox was called "Description", the value would be passed to the "Description" property of the model). Clearly this is not the case and it is instead controlled by the "<%# BindItem.Description %>", however as you can see from the rest of this question I am unable to use this syntax in the "InsertItemTemplate". I cannot believe that the DropDownList is not supported in this scenario, but I cannot find any examples of a DropDownList being used with the 4.5 model bindings using Google or Bing (in fact, there are very few examples of the new model binding in ASP.NET 4.5 using anything other than a couple of TextBox controls).
Can anybody shed any further light on the issue (and preferably tell me what needs to be done)?
Other questions on SO that I have looked at...
All of these use the older style binding methods and not the new methods in 4.5
Thanks.
I've been working on something similar and have been able to get a sample to work, so I figured I would post what I have and see if this helps you.
Here is my page code:
<%@ 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>
And my code behind:
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);
}
}
}
You didn't post your entire ListView sample, so I am taking a guess as to how you might have it set up. Please let me know if this helps and if/how this works for you, as your code looks workable and I'm curious as to what is causing your problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With