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

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Mark Stafford

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

    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 programmaticall y 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 EditItemTemplat es. It just goes back into ReadOnly
    mode. The ModeChanging event is fired but the ModeChanged is not. I
    tried using an ObjectDataSourc e 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 UpdateParameter s. 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 ObjectDataSourc e. 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

  • Mark Stafford

    #2
    Re: DetailsView - Won't switch to Edit mode if databinding programmaticall y

    I figured it out. If you use a ObjectDataSourc e 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(Deta ilsViewMode.Rea dOnly) to change it back to normal view.
    If you don't cancel the update, the DetailsView will attempt to find an
    UpdateMethod in the ObjectDataSourc e 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.dt d">

    <script runat="server">

    protected void Page_Load(objec t 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.A dd(bf);
    }

    CommandField cf = new CommandField();
    cf.ShowEditButt on = true;

    dvTest.Fields.A dd(cf);

    //dvTest.DataSour ce = DataProvider.Ge tData();
    //dvTest.DataBind ();
    }
    }


    protected void dvTest_ModeChan ging(object sender,
    DetailsViewMode EventArgs e)
    {

    }

    protected void dvTest_ModeChan ged(object sender, EventArgs e)
    {

    }

    protected void dvTest_ItemUpda ting(object sender,
    DetailsViewUpda teEventArgs e)
    {
    DataProvider.Up dateData(e.NewV alues);

    e.Cancel = true;
    dvTest.ChangeMo de(DetailsViewM ode.ReadOnly);
    }

    </script>

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <title>Untitl ed Page</title>
    </head>
    <body>
    <form id="form1" runat="server">
    <div>
    <asp:DetailsVie w ID="dvTest" runat="server" AutoGenerateRow s="False"
    DataSourceID="d sData"
    OnItemUpdating= "dvTest_ItemUpd ating"
    OnModeChanged=" dvTest_ModeChan ged"
    OnModeChanging= "dvTest_ModeCha nging">
    </asp:DetailsView >
    <asp:ObjectData Source ID="dsData" runat="server"
    SelectMethod="G etData" TypeName="DataP rovider">
    </asp:ObjectDataS ource>
    </div>
    </form>
    </body>
    </html>


    AppCode/DataProvider.cs
    -----------------------------------------------------------------------------------
    using System;
    using System.Data;
    using System.Collecti ons;
    using System.Collecti ons.Specialized ;
    using System.Web;
    using System.Web.UI;

    public class DataProvider
    {
    public static void UpdateData(IOrd eredDictionary newValues)
    {
    DataTable dt = GetData();
    DataRow dr = dt.Rows[0];

    foreach (DictionaryEntr y de in newValues)
    {
    dr[(string) de.Key] = de.Value;
    }

    HttpContext.Cur rent.Session["TheTable"] = dt;
    }

    public static DataTable GetData()
    {
    DataTable dt;
    object sdt = HttpContext.Cur rent.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.Cur rent.Session["TheTable"] = dt;
    }
    else
    {
    dt = (DataTable) HttpContext.Cur rent.Session["TheTable"];
    }

    return dt;
    }
    }

    Comment

    Working...