I figured it out. If you use a ObjectDataSource but don't provide
UpdateMethod, the ItemUpdating event is still fired so you can update
your db using the e.NewValues passed at the event params. The trick is
to cancel the update using e.Cancel and then call
ChangeMode(DetailsViewMode.ReadOnly) to change it back to normal view.
If you don't cancel the update, the DetailsView will attempt to find an
UpdateMethod in the ObjectDataSource and will blow up. But I have
tested this method and it works.
Here is the code:
DetailsViewTest.aspx
-----------------------------------------------------------------------------------
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
for (int n = 1; n <= 7; n++)
{
BoundField bf = new BoundField();
bf.DataField = "Column" + n;
bf.HeaderText = "Col " + n;
dvTest.Fields.Add(bf);
}
CommandField cf = new CommandField();
cf.ShowEditButton = true;
dvTest.Fields.Add(cf);
//dvTest.DataSource = DataProvider.GetData();
//dvTest.DataBind();
}
}
protected void dvTest_ModeChanging(object sender,
DetailsViewModeEventArgs e)
{
}
protected void dvTest_ModeChanged(object sender, EventArgs e)
{
}
protected void dvTest_ItemUpdating(object sender,
DetailsViewUpdateEventArgs e)
{
DataProvider.UpdateData(e.NewValues);
e.Cancel = true;
dvTest.ChangeMode(DetailsViewMode.ReadOnly);
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp

etailsView ID="dvTest" runat="server" AutoGenerateRows="False"
DataSourceID="dsData"
OnItemUpdating="dvTest_ItemUpdating"
OnModeChanged="dvTest_ModeChanged"
OnModeChanging="dvTest_ModeChanging">
</asp

etailsView>
<asp:ObjectDataSource ID="dsData" runat="server"
SelectMethod="GetData" TypeName="DataProvider">
</asp:ObjectDataSource>
</div>
</form>
</body>
</html>
AppCode/DataProvider.cs
-----------------------------------------------------------------------------------
using System;
using System.Data;
using System.Collections;
using System.Collections.Specialized;
using System.Web;
using System.Web.UI;
public class DataProvider
{
public static void UpdateData(IOrderedDictionary newValues)
{
DataTable dt = GetData();
DataRow dr = dt.Rows[0];
foreach (DictionaryEntry de in newValues)
{
dr[(string) de.Key] = de.Value;
}
HttpContext.Current.Session["TheTable"] = dt;
}
public static DataTable GetData()
{
DataTable dt;
object sdt = HttpContext.Current.Session["TheTable"];
if (sdt == null || !(sdt is DataTable))
{
dt = new DataTable();
dt.Columns.Add("Column1");
dt.Columns.Add("Column2");
dt.Columns.Add("Column3");
dt.Columns.Add("Column4");
dt.Columns.Add("Column5");
dt.Columns.Add("Column6");
dt.Columns.Add("Column7");
DataRow dr = dt.NewRow();
dr["Column1"] = "Data1";
dr["Column2"] = "Data2";
dr["Column3"] = "Data3";
dr["Column4"] = "Data4";
dr["Column5"] = "Data5";
dr["Column6"] = "Data6";
dr["Column7"] = "Data7";
dt.Rows.Add(dr);
HttpContext.Current.Session["TheTable"] = dt;
}
else
{
dt = (DataTable) HttpContext.Current.Session["TheTable"];
}
return dt;
}
}