DetailsView - Won't switch to Edit mode if databinding programmatically

M

Mark Stafford

I am attempting to use a DetailsView control to view some data where
the fields returned by the database are determined at runtime. I
create the TemplateFields on the fly using a class that implements
ITemplate and repopulate the Template properters of TemplateField in
OnInit. And I am DataBinding by getting a DataTable from my db
provider class in Page_Load event. When I databind programmatically in
the Page_Load, the data displays in the ReadOnly mode fine, but when I
click on Edit command button, it does a postback and the data in the
right column (not the headers) disappears and it does not go into Edit
mode or call the EditItemTemplates. It just goes back into ReadOnly
mode. The ModeChanging event is fired but the ModeChanged is not. I
tried using an ObjectDataSource declaritively in the aspx file. Then
it then goes into Edit mode but another issue arises. The fields again
are determined at runtime so I can't hard code the UpdateParameters. I
tried using and Update method that took a DataTable or Hashtable. But
I can't seem to find a way to have it pass me a dynamic data object
when using the ObjectDataSource. If I use a Hashtable, it blows up.
If my update method takes a DataTable, the update method does not get
called nor does the ItemUpdating event get called so that I could
handle it in there. And it gets stuck in Edit mode.

I have a nice welt on my forehead from banging my head against the wall
here. Does anyone have any ideas on how to view/edit data that is
determined runtime? I thought this would have been easy in ASP.NET 2.0
but maybe I am just missing something.

Thanks
Mark
 
M

Mark Stafford

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:DetailsView ID="dvTest" runat="server" AutoGenerateRows="False"
DataSourceID="dsData"
OnItemUpdating="dvTest_ItemUpdating"
OnModeChanged="dvTest_ModeChanged"
OnModeChanging="dvTest_ModeChanging">
</asp:DetailsView>
<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;
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top