Solved

Can't switch modes with DetailsView TemplateField?  (Anyone?  Bueller?)

Posted on 2008-06-23
10
898 Views
Last Modified: 2013-11-07
(This is the third time I've re-posted this question, trying to get attention.  I'm pretty surprised I can't get anyone to look at it.  I've wrapped it up as best as I can, nobody will even try my cut-and-paste code and say "works for me" or "yeah that's weird"??  There appears to be lots of knowledge on this site on DetailsViews, and I'm having some stubborn trouble, and I'm sure it's something simple I'm not doing.  Please, if you're an expert on this stuff and don't like this question, let me know how to rephrase it... or if you can suggest alternate approaches...  )

Hey.  I'm having trouble with switching modes in my DetailsView.  I'm not using a real database, just my own DataTable (which I think should work fine).  It works fine (switching between modes, saving data or not) with BoundFields and CheckBox fields, but when I create my own TemplateField (with a combo box), the controls seem to disappear.

I've provided cut-and-paste code to show the problem.  Create a new webform and (just tested this, works fine):

a) Drop DetailsView1 on it
b) Replace the VB code behind it with the code below.
c) Add the attribute EnableEventValidation="false" to the Page item on the page source, mine looks like:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="FormTest3.aspx.vb" Inherits="FormTest3" EnableEventValidation="false"%>

And you'll see the problem.  Change the data and click "update", and the data saves (into my DataTable, where I can process it on the server), or cancel and it doesn't save.  Then go back to Edit mode and so on.  *Except* for my TemplateField, which seems to go blank on any mode change.

Somehow I'm missing something special that is needed to keep my TemplateField active, an event handler or something.

If anyone has ANY ideas, I'd love to hear them.  This problem has been my showstopper for several days now.  Thanks VERY much.
Partial Class FormTest2

    Inherits System.Web.UI.Page

 

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

 

        If Not IsPostBack Then

 

            ' ****************************************

            '

            ' if I start it out in edit mode, then the combo box template displays

            ' fine, with the dummy defined values

            '

            ' if I start it out in readonly mode, then the label template displays

            ' fine, with the dummy text

            '

            ' but in either case, when I switch to the other mode, the 

            ' template does not display, it's just a blank field

            '

            ' (I do have to set Page EnableEventValidation="false" for some 

            ' reason, or the combo box belches)

            ' 

            ' (was going to add code to set/read the combo box, but for now 

            ' just can't get it to display)

            '

            ' ****************************************

 

            DetailsView1.DefaultMode = DetailsViewMode.Edit

            'DetailsView1.DefaultMode = DetailsViewMode.ReadOnly

 

            ' ****************************************

            ' build a datatable

            ' add columns 'Field1' and 'Field2'

            ' ****************************************

 

            Dim dt As New Data.DataTable

            Session("stored_datatable") = dt

 

            Dim bc As New Data.DataColumn

            bc.ColumnName = "Field1"

            dt.Columns.Add(bc)

 

            Dim bc2 As New Data.DataColumn

            bc2.ColumnName = "Field2"

            dt.Columns.Add(bc2)

 

            Dim bc3 As New Data.DataColumn

            bc3.ColumnName = "Field3"

            dt.Columns.Add(bc3)

 

            Dim bc4 As New Data.DataColumn

            bc4.ColumnName = "Field4"

            dt.Columns.Add(bc4)

 

            ' ****************************************

            ' build the details view to match

            ' ****************************************

 

            With DetailsView1

 

                .AutoGenerateRows = False

                .AutoGenerateEditButton = True

 

                Dim dcf As New BoundField

                dcf.DataField = "Field1"

                dcf.HeaderText = "Field1"

                .Fields.Add(dcf)

 

                Dim dcf2 As New BoundField

                dcf2.DataField = "Field2"

                dcf2.HeaderText = "Field2"

                .Fields.Add(dcf2)

 

                Dim dcf3 As New CheckBoxField

                dcf3.DataField = "Field3"

                dcf3.HeaderText = "Field3"

                .Fields.Add(dcf3)

 

                Dim dcf4 As New TemplateField()

 

                Dim temp_cmb As New TemplateComboBox()

                Dim temp_lbl As New TemplateLabel()

 

                dcf4.ItemTemplate = temp_lbl

                dcf4.EditItemTemplate = temp_cmb

                dcf4.HeaderText = "Field4"

                .Fields.Add(dcf4)

 

            End With

 

            ' ****************************************

            ' add a single row to the datatable

            ' ****************************************

 

            dt.Rows.Add("data1", "data2", True, 3)

 

            ' ****************************************

            ' and bind

            ' ****************************************

 

            DetailsView1.DataSource = dt

            DetailsView1.DataBind()

 

        End If

 

    End Sub

 

    Protected Sub DetailsView1_ModeChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewModeEventArgs) Handles DetailsView1.ModeChanging

 

        ' ****************************************

        ' handle the mode change

        ' rebind to the source table

        ' ****************************************

 

        Dim dv As DetailsView = sender

 

        Dim dt As Data.DataTable = Session("stored_datatable")

 

        dv.DataSource = dt

 

        Select Case e.NewMode

 

            Case DetailsViewMode.ReadOnly : dv.ChangeMode(DetailsViewMode.ReadOnly)

            Case DetailsViewMode.Edit : dv.ChangeMode(DetailsViewMode.Edit)

            Case DetailsViewMode.Insert : dv.ChangeMode(DetailsViewMode.Insert)

 

        End Select

 

        dv.DataBind()

 

    End Sub

 

    Protected Sub DetailsView1_ItemUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewUpdateEventArgs) Handles DetailsView1.ItemUpdating

 

        ' ****************************************

        ' handle the item update

        ' must admit: don't know why all this is necessary, got it from EE

        ' maybe it will become clear later

        ' ****************************************

 

        Dim dv As DetailsView = sender

        Dim dt As Data.DataTable = Session("stored_datatable")

 

        For i As Integer = 0 To dv.Fields.Count - 1

 

            Dim cn As DataControlFieldCell = dv.Rows(i).Cells(0)

            dv.Fields(i).ExtractValuesFromCell(e.Keys, cn, DataControlRowState.Normal, True)

 

            Dim ce As DataControlFieldCell = dv.Rows(i).Cells(1)

            dv.Fields(i).ExtractValuesFromCell(e.NewValues, ce, DataControlRowState.Edit, False)

 

        Next

 

        Dim cnt As Integer = 0

 

        For Each key As String In e.NewValues.Keys

            dt.Rows(0).Item(cnt) = e.NewValues(key)

            cnt += 1

        Next

 

        dv.DataSource = dt

        dv.ChangeMode(DetailsViewMode.ReadOnly)

        dv.DataBind()

 

    End Sub

 

    ' ****************************************

    ' my template classes for the combo box

    ' ****************************************

 

    Public Class TemplateComboBox

 

        Implements ITemplate

 

        Dim WithEvents m_combobox As New DropDownList

 

        Public Sub New()

 

            Dim L1 As New ListItem

            L1.Text = "Choice1"

            L1.Value = "1"

            m_combobox.Items.Add(L1)

            Dim L2 As New ListItem

            L2.Text = "Choice2"

            L2.Value = "2"

            m_combobox.Items.Add(L2)

 

        End Sub

 

        Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.InstantiateIn

 

            container.Controls.Add(m_combobox)

 

        End Sub

 

    End Class

 

    Public Class TemplateLabel

 

        Implements ITemplate

 

        Dim m_label As New Label

 

        Public Sub New()

 

            m_label.Text = "dummy text"

 

        End Sub

 

        Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.InstantiateIn

 

            container.Controls.Add(m_label)

 

        End Sub

 

    End Class

 

End Class

Open in new window

0
Comment
Question by:riceman0
  • 5
  • 4
10 Comments
 
LVL 33

Expert Comment

by:raterus
ID: 21851439
You have the dynamic control blues, that is any controls you create dynamically, you have to rebuild them on each postback.

Basically if you want this to work, you have to run the following code (below) on each postback in page_load to rebuild the controls in the DetailsView.


            With DetailsView1

 

                .AutoGenerateRows = False

                .AutoGenerateEditButton = True

 

                Dim dcf As New BoundField

                dcf.DataField = "Field1"

                dcf.HeaderText = "Field1"

                .Fields.Add(dcf)

 

                Dim dcf2 As New BoundField

                dcf2.DataField = "Field2"

                dcf2.HeaderText = "Field2"

                .Fields.Add(dcf2)

 

                Dim dcf3 As New CheckBoxField

                dcf3.DataField = "Field3"

                dcf3.HeaderText = "Field3"

                .Fields.Add(dcf3)

 

                Dim dcf4 As New TemplateField()

 

                Dim temp_cmb As New TemplateComboBox()

                Dim temp_lbl As New TemplateLabel()

 

                dcf4.ItemTemplate = temp_lbl

                dcf4.EditItemTemplate = temp_cmb

                dcf4.HeaderText = "Field4"

                .Fields.Add(dcf4)

 

            End With

Open in new window

0
 

Author Comment

by:riceman0
ID: 21851515
Thanks very much for the answer!!!

Will play around with that further, but when I try that on every reload it seems to add more and more fields to the control... which seems to suggest it does not need rebuilding... ?  Is this still the "dynamic control blues" (thanks for the concept) you're talking about?  After all I actually dropped the DetailsView in the designer, and it is visible in the ASP source, not instantiated in the code behind (it's just my DataTable that is created in the code behind).  Doesn't that make it statically created?

I will play around right now with recreating my TemplateField on every load though.  Maybe that element defies client-side persistence or something.  Of course I just sort of made up those words.
0
 
LVL 33

Expert Comment

by:raterus
ID: 21851575
Actually, I was baffled that those other controls weren't disappearing, usually it's all or nothing.  I figured you still were down with the blues (the most common issue, by far, I see on this boards)  How does your .aspx page look, specifically the DetailsView?

No, any control you instantiate itself, and add to another control's controls section is a "dynamic" control.  The only thing I can gather about your issue is that the DetailsView can actually persist the very basic of columns.  Since the Templatefield is a bit more uncommon, it doesn't mess with that.  I dunno, I've never tested it and if it is like this, I've never seen another control act in this manner.
0
 

Author Comment

by:riceman0
ID: 21851686

In the designer (if that's what you mean...) the DetailsView is just an empty control, the default three fields.

But it's funny, on inspection the DetailsView seems to retain nearly all of its properties on postbacks, like .AutoGenerateRows remains false, and it keeps the 4 fields (even though I only define them on the original load).  The fourth field even remains a TemplateField -- however both the EditItemTemplate and ItemTemplate properties of the TemplateField have vaporized to 'Nothing.'  Seems like everything is persistent but those template pointers.  I'll try to refresh those template references every time (although I have a faint recollection of trying that before to no avail, and concluded something more fundamental was wrong...)
0
 
LVL 33

Expert Comment

by:raterus
ID: 21851945
Switch to the HTML view and find something like <asp:DetailsView ...>  Post everything around that.  I think your designer is already adding these fields that are retaining their value, which is expected..
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 

Author Comment

by:riceman0
ID: 21851957

As empty as can be, right?  That runat=server is interesting, although I assume that's default...
<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="DetailsView1" runat="server" Height="50px" Width="125px">

        </asp:DetailsView>

    

    </div>

    </form>

</body>

</html>

Open in new window

0
 
LVL 33

Accepted Solution

by:
raterus earned 400 total points
ID: 21855259
Yeah, that is perfectly fine.

I "guess" detailsview actually persists the controls you add dynamically, strange, but I stepped through the code and it's doing exactly that.

Regardless, I was able to fix your missing text problem by adding this code (below).  Take note of the .Fields.Clear() method I'm using too.
        With DetailsView1

            .Fields.Clear()

            .AutoGenerateRows = False

            .AutoGenerateEditButton = True
 

            Dim dcf As New BoundField

            dcf.DataField = "Field1"

            dcf.HeaderText = "Field1"

            .Fields.Add(dcf)
 

            Dim dcf2 As New BoundField

            dcf2.DataField = "Field2"

            dcf2.HeaderText = "Field2"

            .Fields.Add(dcf2)
 

            Dim dcf3 As New CheckBoxField

            dcf3.DataField = "Field3"

            dcf3.HeaderText = "Field3"

            .Fields.Add(dcf3)
 

            Dim dcf4 As New TemplateField()
 

            Dim temp_cmb As New TemplateComboBox()

            Dim temp_lbl As New TemplateLabel()
 

            dcf4.ItemTemplate = temp_lbl

            dcf4.EditItemTemplate = temp_cmb

            dcf4.HeaderText = "Field4"

            .Fields.Add(dcf4)
 

        End With

Open in new window

0
 

Assisted Solution

by:NorthReno
NorthReno earned 100 total points
ID: 21860491
Have you tried building all of your controls and assigning all of the attributes in the ASPX page?  I have had pretty good luck with my details view.  The problems came when I tried adding things on the fly.  I haven't tried changing the modes dynamically as I always want it to be in insert mode.

It is a rather complex Details view complete with ItemTemplates, and InsertTemplates.  By the way, what modes are you using? Edit and Insert?  If so, I believe that you will need both EditTemplates and InsertTemplates.  Take a look at my snippit below and see if it is of any help.

At the beginning,  I set all of the values I have to have on start up, including the DefaultMode.  For each control everything is also statically set.  During processing, I have certain fields I enable and disable, turn visible and invisible... dynamically - regardless of postback status.

Hope it helps.
       <asp:DetailsView ID="dtvReceiptsEntry" 

                         runat="server" 

                         Enabled="false"

                         AutoGenerateRows="false"

                         Height="33px" 

                         Width="45%"

                         DefaultMode="Insert"

                         BackColor="#DEBA84" 

                         BorderColor="#DEBA84" 

                         BorderStyle="None" 

                         BorderWidth="1px" 

                         CellPadding="2" 

                         CellSpacing="1" GridLines="Both">
 

            <FooterStyle BackColor="#F7DFB5" ForeColor="#8C4510" />

            <RowStyle BackColor="#FFF7E7" ForeColor="#8C4510" />

            <PagerStyle ForeColor="#8C4510"  />

            <HeaderStyle BackColor="#A55129" Font-Bold="True" ForeColor="White" />

            <EditRowStyle BackColor="#738A9C" Font-Bold="True" ForeColor="White" HorizontalAlign="Left"  />

            <Fields>

                <asp:TemplateField HeaderText="Transporter FEIN">

                    <InsertItemTemplate>

                        <asp:TextBox ID="txtCarrierFEIN"   

					                 runat="server" 

                                     CssClass="Bod8"

					                 Width="80px">

					    </asp:TextBox>
 

                    </InsertItemTemplate>

                </asp:TemplateField>

                <asp:TemplateField HeaderText="Transporter Name">

                    <InsertItemTemplate>

                        <asp:TextBox ID="txtCarrierName" 

                                     CssClass="Bod8"

                                     runat="server"

                                     width="250px">

                        </asp:TextBox>
 

                    </InsertItemTemplate>

                </asp:TemplateField>

                <asp:TemplateField HeaderText="Mode Type">

                    <InsertItemTemplate>

                       <asp:DropDownList ID="ddlModeType" 

                                          runat="server" 

                                          DataSourceID="odsuf_rtdata_mfmo"

                                          DataTextField="data_txt" 

                                          DataValueField="key_txt"  

                                          SelectedValue='<%# Eval ("MODE_TY") %>' 

					                      Width="150px" 

                                          CssClass="Bod8">

                        </asp:DropDownList>

                    </InsertItemTemplate>

                </asp:TemplateField>

                <asp:TemplateField HeaderText="Origin City">

                    <InsertItemTemplate>

                        <asp:TextBox ID="txtOrigCity" 

					                 runat="server" 

					                 Width="250px"

					                 CssClass="Bod8">

					    </asp:TextBox>
 

                    </InsertItemTemplate>

                </asp:TemplateField>

                <asp:TemplateField HeaderText="Origin State">

                    <InsertItemTemplate>

                        <asp:DropDownList ID="ddlOrigState" 

			                              runat="server" 

			                              Width="100px"

			                              CssClass="Bod8"  

			                              DatasourceID="odsuf_rtdata_gsta" 

			                              DataTextField="data_txt" 

			                              DataValueField="key_txt" 

			                              SelectedValue='<%# Eval("Orig State") %>'>

			            </asp:DropDownList>
 

                    </InsertItemTemplate>

                </asp:TemplateField>

                <asp:TemplateField HeaderText="Dest City">

                    <InsertItemTemplate>

                        <asp:TextBox ID="txtDestCity"    

					                 runat="server" 

					                 Width="250px"

					                 CssClass="Bod8">

					    </asp:TextBox>
 

                    </InsertItemTemplate>

                </asp:TemplateField>

                <asp:TemplateField HeaderText="Dest State">

                    <InsertItemTemplate>

                        <asp:DropDownList ID="ddlDestState" 

					                      runat="server" 

					                      Width="100px"

					                      CssClass="Bod8" 

					                      DatasourceID="odsuf_rtdata_gsta" 

						                  DataTextField="data_txt" 

						                  DataValueField="key_txt" 

						                  SelectedValue='<%# Eval("Dest State") %>'>

						</asp:DropDownList>
 

                    </InsertItemTemplate>

                </asp:TemplateField>

                <asp:TemplateField HeaderText="Seller's FEIN">

                    <InsertItemTemplate>

                        <asp:TextBox ID="txtSellerFEIN" 

					                 runat="server" 

					                 Width="80px"

					                 CssClass="Bod8">

					    </asp:TextBox>
 

                    </InsertItemTemplate>

                </asp:TemplateField>

                <asp:TemplateField HeaderText="Received From">

                    <InsertItemTemplate>

                        <asp:TextBox ID="txtRcvdFrom" 

					                 runat="server" 

					                 Width="250px"

					                 CssClass="Bod8">

					    </asp:TextBox>
 

                    </InsertItemTemplate>

                </asp:TemplateField>

                <asp:TemplateField HeaderText="Date Received">

                    <InsertItemTemplate>

                        <asp:TextBox ID="txtDateRcvd" 

					                 runat="server" 

					                 Width="80px"

					                 CssClass="Bod8">

					    </asp:TextBox>
 

                    </InsertItemTemplate>

                </asp:TemplateField>

                <asp:TemplateField HeaderText="BOL/Manifest">

                    <InsertItemTemplate>

                        <asp:TextBox ID="txtBOL" 

					                 runat="server" 

					                 Width="100px"

					                 CssClass="Bod8">

					    </asp:TextBox>
 

                    </InsertItemTemplate>

                </asp:TemplateField>

                <asp:TemplateField HeaderText="Net Gallons">

                    <InsertItemTemplate>

                        <asp:TextBox ID="txtNetGal" 

					                 runat="server" 

					                 Width="80px"

					                 CssClass="Bod8">

					    </asp:TextBox>                    
 

					</InsertItemTemplate>

                </asp:TemplateField>

                <asp:TemplateField HeaderText="Gross Gallons">

                    <InsertItemTemplate>

                        <asp:TextBox ID="txtGrossGal" 

					                 runat="server" 

					                 Width="80px" 

					                 CssClass="Bod8">

					    </asp:TextBox>
 

					   

                    </InsertItemTemplate>                

                </asp:TemplateField>

                <asp:TemplateField HeaderText="Billed Gallons">

                    <InsertItemTemplate>

                        <asp:TextBox ID="txtBillGal" 

					                 runat="server" 

					                 Width="80px" 

					                 CssClass="Bod8">

					    </asp:TextBox>
 

                    </InsertItemTemplate>                

                </asp:TemplateField>

            </Fields>
 

        </asp:DetailsView>

Open in new window

0
 

Author Comment

by:riceman0
ID: 21907536
By the way I had to set this aside for a few days (fighting a fire on a different project) but I will get back to it  ASAP, and I do appreciate the help!
0
 

Author Comment

by:riceman0
ID: 22149312
Haven't licked this problem yet, I'm just closing this out to award the points to the deserving parties.  Will post the solution when I achieve it.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
A short film showing how OnPage and Connectwise integration works.
This is a video describing the growing solar energy use in Utah. This is a topic that greatly interests me and so I decided to produce a video about it.

919 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now