riceman0
asked on
Can't switch modes with DetailsView TemplateField? (Anyone? Bueller?)
(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="fal se" to the Page item on the page source, mine looks like:
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="FormTest3.aspx.v b" Inherits="FormTest3" EnableEventValidation="fal se"%>
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.
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="fal
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="FormTest3.aspx.v
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
ASKER
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.
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.
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.
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.
ASKER
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...)
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..
ASKER
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>
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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!
ASKER
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.
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.
Open in new window