I am trying to create a custom EditForm for use with the RadGrid. When I edit or insert a record, the other records in the grid display incorrectly.
My app:
- simple ASP.NET 4.5 web application
- OS: Windows 8.1
- IDE: VS2013.
- Telerik version - I am a consultant and using the DLLs provided by my client, so I don't have any sort of Telerik SDK installed. The version of Telerik.Web.UI.dll I am using is 2013.1.417.35 (17MB, dated 5/12/2014 7:50pm).
- Browser: Google Chrome Version 36.0.1985.125 m. I also tested on IE 11 11.0.9600.17207 (Update version 11.0.10).
TestGrid.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TestGrid.aspx.cs" Inherits="TestGrid" %>
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<telerik:RadScriptManager runat="server" ID="RadScriptManager1" />
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="dataGrid">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="dataGrid" LoadingPanelID="RadAjaxLoadingPanel1"/>
<telerik:AjaxUpdatedControl ControlID="divMsgs" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManager>
<telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel1" runat="server" />
<div>
<telerik:RadGrid runat="server" ID="dataGrid" AutoGenerateColumns="False" Width="300px">
<MasterTableView DataKeyNames="Id" CommandItemDisplay="Top" EditMode="EditForms">
<Columns>
<telerik:GridEditCommandColumn />
<telerik:GridBoundColumn HeaderText="Id" DataField="Id" Display="False" UniqueName="Id" />
<telerik:GridBoundColumn HeaderText="Name" DataField="Name" UniqueName="Name" />
<telerik:GridBoundColumn HeaderText="Age" DataField="Age" UniqueName="Age" />
</Columns>
<EditFormSettings EditFormType="Template">
<FormTemplate>
<table>
<thead>
<th colspan="2">Person Info</th>
</thead>
<tbody>
<tr>
<td>Name</td>
<td><asp:TextBox ID="tbName" runat="server" Text='<%# Bind("Name") %>' /></td>
</tr>
<tr>
<td>Age</td>
<td><asp:TextBox ID="tbAge" runat="server" Text='<%# Bind("Age") %>' /></td>
</tr>
<tr>
<td align="right" colspan="2">
<asp:Button ID="btnUpdate" runat="server"
Text='<%# (Container is GridEditFormInsertItem) ? "Insert" : "Update" %>'
CommandName='<%# (Container is GridEditFormInsertItem) ? "PerformInsert" : "Update" %>' />
<asp:Button ID="btnCancel" runat="server"
Text="Cancel" CausesValidation="False" CommandName="Cancel" />
</td>
</tr>
</tbody>
</table>
</FormTemplate>
</EditFormSettings>
</MasterTableView>
</telerik:RadGrid>
</div>
</form>
</body>
</html>
TestGrid.aspx.cs:
using System;
using System.Collections;
using System.Diagnostics;
using Telerik.Web.UI;
public partial class TestGrid : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
dataGrid.NeedDataSource += dataGrid_NeedDataSource;
dataGrid.InsertCommand += dataGrid_InsertCommand;
dataGrid.UpdateCommand += dataGrid_UpdateCommand;
}
void dataGrid_NeedDataSource(object sender, GridNeedDataSourceEventArgs e) {
dataGrid.DataSource = People;
}
public People People {
get {
var obj = this.ViewState["_people"];
if (obj != null) return (People)obj;
var people = People.AllPeople;
this.ViewState["_people"] = people;
return people;
}
}
void dataGrid_UpdateCommand(object sender, GridCommandEventArgs e) {
var values = new Hashtable();
e.Item.OwnerTableView.ExtractValuesFromItem(values, e.Item as GridEditableItem);
foreach (DictionaryEntry de in values) Debug.WriteLine("{0}={1}", de.Key, de.Value);
People.UpdatePerson(values);
this.ViewState["_people"] = People;
}
void dataGrid_InsertCommand(object sender, GridCommandEventArgs e) {
var values = new Hashtable();
e.Item.OwnerTableView.ExtractValuesFromItem(values, e.Item as GridEditableItem);
People.AddPerson(values);
this.ViewState["_people"] = People;
}
}
App_Code\Person.cs:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
[Serializable]
public class Person {
static int _nextId;
private int m_id;
public int Id {
get { return m_id; }
set {
m_id = value;
_nextId = Math.Max(m_id + 1, _nextId);
}
}
public string Name { get; set; }
public int Age { get; set; }
public Person(int id, string name, int age) {
Id = id;
Name = name;
Age = age;
}
public Person() {}
public void AssignId() {
Id = _nextId;
}
public override string ToString() {
return string.Format("#{0}: {1} [{2}]", Id, Name, Age);
}
public void Update(Hashtable values) {
Name = (string)values["Name"];
Age = int.Parse((string)values["Age"]);
}
}
[Serializable]
public class People : List<Person> {
public People() {
Add(new Person(1, "David", 43));
Add(new Person(2, "Rebecca", 40));
}
public void UpdatePerson(Hashtable values) {
var person = this.FirstOrDefault(p => p.Id == int.Parse((string)values["Id"]));
if (person == null) throw new NullReferenceException("Person not found (" + values["Id"] + ")");
person.Update(values);
}
public void AddPerson(Hashtable values) {
var person = new Person();
person.AssignId();
person.Update(values);
Add(person);
}
static People s_people;
public static People AllPeople { get { return s_people ?? (s_people = new People()); } }
}
I have attached three files:
- Pic1.png: Viewing the data (works fine)
- Pic2.png: Edit the "David" record
- Pic3.png: Insert a new record
I tried viewing source after clicking Insert, but it appears that source in that case is simply the source I see when I view the data. The custom edit form controls don't appear in that source.
Note that this is the same behavior as in this post:
http://www.telerik.com/forums/problem-editform-template--edit-and-new-record
My app:
- simple ASP.NET 4.5 web application
- OS: Windows 8.1
- IDE: VS2013.
- Telerik version - I am a consultant and using the DLLs provided by my client, so I don't have any sort of Telerik SDK installed. The version of Telerik.Web.UI.dll I am using is 2013.1.417.35 (17MB, dated 5/12/2014 7:50pm).
- Browser: Google Chrome Version 36.0.1985.125 m. I also tested on IE 11 11.0.9600.17207 (Update version 11.0.10).
TestGrid.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TestGrid.aspx.cs" Inherits="TestGrid" %>
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<telerik:RadScriptManager runat="server" ID="RadScriptManager1" />
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="dataGrid">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="dataGrid" LoadingPanelID="RadAjaxLoadingPanel1"/>
<telerik:AjaxUpdatedControl ControlID="divMsgs" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManager>
<telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel1" runat="server" />
<div>
<telerik:RadGrid runat="server" ID="dataGrid" AutoGenerateColumns="False" Width="300px">
<MasterTableView DataKeyNames="Id" CommandItemDisplay="Top" EditMode="EditForms">
<Columns>
<telerik:GridEditCommandColumn />
<telerik:GridBoundColumn HeaderText="Id" DataField="Id" Display="False" UniqueName="Id" />
<telerik:GridBoundColumn HeaderText="Name" DataField="Name" UniqueName="Name" />
<telerik:GridBoundColumn HeaderText="Age" DataField="Age" UniqueName="Age" />
</Columns>
<EditFormSettings EditFormType="Template">
<FormTemplate>
<table>
<thead>
<th colspan="2">Person Info</th>
</thead>
<tbody>
<tr>
<td>Name</td>
<td><asp:TextBox ID="tbName" runat="server" Text='<%# Bind("Name") %>' /></td>
</tr>
<tr>
<td>Age</td>
<td><asp:TextBox ID="tbAge" runat="server" Text='<%# Bind("Age") %>' /></td>
</tr>
<tr>
<td align="right" colspan="2">
<asp:Button ID="btnUpdate" runat="server"
Text='<%# (Container is GridEditFormInsertItem) ? "Insert" : "Update" %>'
CommandName='<%# (Container is GridEditFormInsertItem) ? "PerformInsert" : "Update" %>' />
<asp:Button ID="btnCancel" runat="server"
Text="Cancel" CausesValidation="False" CommandName="Cancel" />
</td>
</tr>
</tbody>
</table>
</FormTemplate>
</EditFormSettings>
</MasterTableView>
</telerik:RadGrid>
</div>
</form>
</body>
</html>
TestGrid.aspx.cs:
using System;
using System.Collections;
using System.Diagnostics;
using Telerik.Web.UI;
public partial class TestGrid : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
dataGrid.NeedDataSource += dataGrid_NeedDataSource;
dataGrid.InsertCommand += dataGrid_InsertCommand;
dataGrid.UpdateCommand += dataGrid_UpdateCommand;
}
void dataGrid_NeedDataSource(object sender, GridNeedDataSourceEventArgs e) {
dataGrid.DataSource = People;
}
public People People {
get {
var obj = this.ViewState["_people"];
if (obj != null) return (People)obj;
var people = People.AllPeople;
this.ViewState["_people"] = people;
return people;
}
}
void dataGrid_UpdateCommand(object sender, GridCommandEventArgs e) {
var values = new Hashtable();
e.Item.OwnerTableView.ExtractValuesFromItem(values, e.Item as GridEditableItem);
foreach (DictionaryEntry de in values) Debug.WriteLine("{0}={1}", de.Key, de.Value);
People.UpdatePerson(values);
this.ViewState["_people"] = People;
}
void dataGrid_InsertCommand(object sender, GridCommandEventArgs e) {
var values = new Hashtable();
e.Item.OwnerTableView.ExtractValuesFromItem(values, e.Item as GridEditableItem);
People.AddPerson(values);
this.ViewState["_people"] = People;
}
}
App_Code\Person.cs:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
[Serializable]
public class Person {
static int _nextId;
private int m_id;
public int Id {
get { return m_id; }
set {
m_id = value;
_nextId = Math.Max(m_id + 1, _nextId);
}
}
public string Name { get; set; }
public int Age { get; set; }
public Person(int id, string name, int age) {
Id = id;
Name = name;
Age = age;
}
public Person() {}
public void AssignId() {
Id = _nextId;
}
public override string ToString() {
return string.Format("#{0}: {1} [{2}]", Id, Name, Age);
}
public void Update(Hashtable values) {
Name = (string)values["Name"];
Age = int.Parse((string)values["Age"]);
}
}
[Serializable]
public class People : List<Person> {
public People() {
Add(new Person(1, "David", 43));
Add(new Person(2, "Rebecca", 40));
}
public void UpdatePerson(Hashtable values) {
var person = this.FirstOrDefault(p => p.Id == int.Parse((string)values["Id"]));
if (person == null) throw new NullReferenceException("Person not found (" + values["Id"] + ")");
person.Update(values);
}
public void AddPerson(Hashtable values) {
var person = new Person();
person.AssignId();
person.Update(values);
Add(person);
}
static People s_people;
public static People AllPeople { get { return s_people ?? (s_people = new People()); } }
}
I have attached three files:
- Pic1.png: Viewing the data (works fine)
- Pic2.png: Edit the "David" record
- Pic3.png: Insert a new record
I tried viewing source after clicking Insert, but it appears that source in that case is simply the source I see when I view the data. The custom edit form controls don't appear in that source.
Note that this is the same behavior as in this post:
http://www.telerik.com/forums/problem-editform-template--edit-and-new-record