By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,853 Members | 995 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,853 IT Pros & Developers. It's quick & easy.

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

P: n/a
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

Aug 28 '06 #1
Share this Question
Share on Google+
1 Reply


P: n/a
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;
}
}

Aug 28 '06 #2

This discussion thread is closed

Replies have been disabled for this discussion.