Odd FormView behaviour on update

J

J055

Hi

I have a PlaceHolder control inside a FormView EditItemTemplate:

<asp:placeHolder ID="phResponseText" runat="server">
<tr>
<td>
<asp:Label ID="lblResponseText" runat="server"></asp:Label></td>
<td>
<asp:TextBox ID="tbResponseText" runat="server" Text='<%#
Bind("ResponseText") %>'></asp:TextBox></td>
</tr>
</asp:placeHolder>

<asp:Button ID="btnUpdate" runat="server" CommandName="Update"
Text="Publish" />

In the Page_Load event I run a routine which makes phResponseText.Visible =
false on each first page load and postbacks depending on the value of
another DropDownList. This works as expected when other controls are
AutoPostBack for example but when the FormView btnUpdate is clicked the page
is postback and the phResponseText PlaceHolderer is displayed as in the
declarative state but completely ignores the programmatic property settings
in Page_Load. I've run a trace on the Visible property in both the Page_Load
and Page_PreRender events and the Visible property shows as false. Can
someone tell me what can possibly be wrong?

Thanks
Andrew
 
S

Steven Cheng[MSFT]

Hello Andrew,

From your description, you're putting a placeholder control in FromView's
EditTemplate, and you'll programmatically determine the placeholder's
Visibility according to another dropdownlist's selected item. However, you
found that the placeholder's visiblity doesn't be as expected when you try
perform updating on the Formview, correct?

As for this problem, I still have something need to confirm on your page:

1. Whether the dropdownlist is in FormView or ouside the Formview, but on
the same page.

2. How did you programmatically set the DropDownList's Visibilty and in
which event (page or FormView's) did you put the code

3. When you click update button(or postback the page to trigger FormView's
update command), the formView should return back to readonly mode after the
postback. When did you check the visibility? Do you mean you check in the
updating event(or any other event during the update comand postback)?

I've created a test page on my side based on my understanding. And I put
the programamtic visibility code(for the placeholder) in FormView's Load
event. You can refer to it and let me know if there is anything I missed.


===========aspx=================
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DropDownList ID="DropDownList1" runat="server">
<asp:ListItem>aaa</asp:ListItem>
<asp:ListItem>bbb</asp:ListItem>
<asp:ListItem>ccc</asp:ListItem>
<asp:ListItem>ddd</asp:ListItem>
</asp:DropDownList><br />
<asp:FormView ID="FormView1" runat="server"
DataKeyNames="AddressTypeID" DataSourceID="SqlDataSource1"
OnItemCreated="FormView1_ItemCreated"
OnItemUpdating="FormView1_ItemUpdating" OnLoad="FormView1_Load"
OnModeChanged="FormView1_ModeChanged">
<EditItemTemplate>
AddressTypeID:
<asp:Label ID="AddressTypeIDLabel1" runat="server"
Text='<%# Eval("AddressTypeID") %>'></asp:Label><br />
Name:
<asp:TextBox ID="NameTextBox" runat="server" Text='<%#
Bind("Name") %>'></asp:TextBox><br />
<hr />
&nbsp;

<asp:placeHolder ID="PlaceHolder1" runat="server">
<table>
<tr>
<td>
<asp:Label ID="lblResponseText"
runat="server">Response Text: </asp:Label></td>
<td>
<asp:TextBox ID="tbResponseText"
runat="server" Text='<%# Bind("Name") %>'></asp:TextBox>
</td>
</tr>
</table>
</asp:placeHolder>


<br />
<hr />
<br />
<asp:LinkButton ID="UpdateButton" runat="server"
CausesValidation="True" CommandName="Update"
Text="Update"></asp:LinkButton>
<asp:LinkButton ID="UpdateCancelButton" runat="server"
CausesValidation="False" CommandName="Cancel"
Text="Cancel"></asp:LinkButton>
</EditItemTemplate>
<InsertItemTemplate>
Name:
<asp:TextBox ID="NameTextBox" runat="server" Text='<%#
Bind("Name") %>'>
</asp:TextBox><br />
<asp:LinkButton ID="InsertButton" runat="server"
CausesValidation="True" CommandName="Insert"
Text="Insert">
</asp:LinkButton>
<asp:LinkButton ID="InsertCancelButton" runat="server"
CausesValidation="False" CommandName="Cancel"
Text="Cancel">
</asp:LinkButton>
</InsertItemTemplate>
<ItemTemplate>
AddressTypeID:
<asp:Label ID="AddressTypeIDLabel" runat="server" Text='<%#
Eval("AddressTypeID") %>'></asp:Label><br />
Name:
<asp:Label ID="NameLabel" runat="server" Text='<%#
Bind("Name") %>'></asp:Label><br />
<asp:LinkButton ID="EditButton" runat="server"
CausesValidation="False" CommandName="Edit"
Text="Edit"></asp:LinkButton>
</ItemTemplate>
</asp:FormView>

</div>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>"
SelectCommand="SELECT AddressTypeID, Name FROM
Person.AddressType" UpdateCommand="UPDATE Person.AddressType SET">
</asp:SqlDataSource>
<asp:Button ID="Button1" runat="server" Text="Button" />
</form>
</body>
</html>

=========code behind=============
public partial class FormViewPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}
protected void FormView1_ItemCreated(object sender, EventArgs e)
{

}
protected void FormView1_ModeChanged(object sender, EventArgs e)
{

}
protected void FormView1_Load(object sender, EventArgs e)
{
Response.Write("<br/>FormView1_Load+FormView1_CurrentMode: " +
FormView1.CurrentMode);

if (FormView1.CurrentMode == FormViewMode.Edit)
{
if (DropDownList1.SelectedValue == "ccc")
{
FormView1.FindControl("PlaceHolder1").Visible = true;
}
else
{
FormView1.FindControl("PlaceHolder1").Visible = false;
}

}
}
protected void FormView1_ItemUpdating(object sender,
FormViewUpdateEventArgs e)
{
Response.Write("<br/>FormView1_ItemUpdating+FormView1_CurrentMode:
" + FormView1.CurrentMode);

if (FormView1.CurrentMode == FormViewMode.Edit)
{
if (DropDownList1.SelectedValue == "ccc")
{
Response.Write("<br/>Visible: " +
FormView1.FindControl("PlaceHolder1").Visible);
}


}

e.Cancel = true;
}
}
==================================

Hope this helps some. If there is any other questions, please feel free to
let me know.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



==================================================

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.



Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.

==================================================



This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

J055

Hi Steven

Please see my answers between your text below.
From your description, you're putting a placeholder control in FromView's
EditTemplate, and you'll programmatically determine the placeholder's
Visibility according to another dropdownlist's selected item. However, you
found that the placeholder's visiblity doesn't be as expected when you try
perform updating on the Formview, correct?

This is correct.
1. Whether the dropdownlist is in FormView or ouside the Formview, but on
the same page.

The dropdownlist which determines the placeholder's visibility is inside the
FormView's EditTemplate too.
2. How did you programmatically set the DropDownList's Visibilty and in
which event (page or FormView's) did you put the code

I used the Page load event to start with but tried the FormViews Load event
too which gives the same result.
3. When you click update button(or postback the page to trigger FormView's
update command), the formView should return back to readonly mode after
the
postback. When did you check the visibility? Do you mean you check in the
updating event(or any other event during the update comand postback)?

when the update command is fired I want the page to save and reload in Edit
mode again. This is my FormView Load event

protected void fvPub_Load(object sender, EventArgs e)
{
if (Int32.TryParse(Request.QueryString["PubID"], out _pubID) == false)

{

fvPub.DefaultMode = FormViewMode.Insert;

}


if (_pubID != 0)
{
fvPub.DefaultMode = FormViewMode.Edit;
}

DropDownList ddlResponseType =
(DropDownList)fvPub.FindControl("ddlResponseType");
phResponseText = (PlaceHolder)fvPub.FindControl("phResponseText");
//...
ResponseTypes respType = (ResponseTypes)Enum.Parse(typeof(ResponseTypes),
ddlResponseType.SelectedValue);
switch (respType)
{
case ResponseTypes.None:
phResponseText.Visible = false;
break;
case ResponseTypes.URL:
phResponseText.Visible = true;
//...break;
}
}

If I cancel the updating event then the page works as expected but obviously
i don't want to do that. I don't understand the purpose of this behaviour. I
want the user to be able to save changes to the page (like a windows form
'Apply' button) and then have the page reload back in edit mode.
protected void fvPub_ItemUpdating(object sender, FormViewUpdateEventArgs e)

{

e.Cancel = true;

}
I've created a test page on my side based on my understanding. And I put
the programamtic visibility code(for the placeholder) in FormView's Load
event. You can refer to it and let me know if there is anything I missed.

You've understood everything I'm doing I think. Can you give me your
recommendations?

Thank you.
Andrew
 
S

Steven Cheng[MSFT]

Hello Andrew,

After some further research, I think we may need to do some changes here.
Here are what I have got so far:

** If you want to make sure the visiblity of the nested placeholder
synchronous to the dropdownlist's selected value in all mode(no matter
whether the FormView has entered edit mode or not), I think you need to set
the DropDownList as "AutoPostback=true".

** Instead of using Load event, we should put the code which set the
Visiblity of nested placeholder(according to dropdownlist's selected value)
in FormView's PreRender event. Since that's the last event we can change
its status, and at that time we can ensure that the DropDownlist.Selected
Value(get at that time) is update to date

** To make the FormView still remain Edit mode after successfully update
the backend database, I think you can add a private page variable (as a
flag) to control the FormView's Mode. And you need to add code in
FormView's PreRender event to set its Mode according to this flag variable.

I have pasted my complete test page's aspx and codebehind below, you can
refer to it and get what I current use(the important part are all in
codebehind). If you feel necessary, I can also email the test pages to you.

==============aspx=======================

<form id="form1" runat="server">
<div>
<asp:DropDownList ID="DropDownList1" runat="server"
AutoPostBack="True">
<asp:ListItem>aaa</asp:ListItem>
<asp:ListItem>bbb</asp:ListItem>
<asp:ListItem>ccc</asp:ListItem>
</asp:DropDownList><br />
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ASPNETTestDBConnectionString %>"
DeleteCommand="DELETE FROM [RVTable] WHERE [id] = @id"
InsertCommand="INSERT INTO [RVTable] ([name]) VALUES (@name)"
SelectCommand="SELECT [name], [id] FROM [RVTable]"
UpdateCommand="UPDATE [RVTable] SET [name] = @name WHERE [id] = @id">
<DeleteParameters>
<asp:parameter Name="id" Type="Int64" />
</DeleteParameters>
<UpdateParameters>
<asp:parameter Name="name" Type="String" />
<asp:parameter Name="id" Type="Int64" />
</UpdateParameters>
<InsertParameters>
<asp:parameter Name="name" Type="String" />
</InsertParameters>
</asp:SqlDataSource>
&nbsp;</div>
<asp:FormView ID="FormView1" runat="server" DataKeyNames="id"
DataSourceID="SqlDataSource1" OnPreRender="FormView1_PreRender"
OnItemUpdated="FormView1_ItemUpdated"
OnItemUpdating="FormView1_ItemUpdating">
<EditItemTemplate>
name:
<asp:TextBox ID="nameTextBox" runat="server" Text='<%#
Bind("name") %>'>
</asp:TextBox><br />
id:
<asp:Label ID="idLabel1" runat="server" Text='<%#
Eval("id") %>'></asp:Label><br />
<asp:placeHolder ID="PlaceHolder1" runat="server">
<br /><hr /><br />
<asp:Label ID="Label1" runat="server" Text="Additional
Input"></asp:Label>
<asp:TextBox ID="txtInput" runat="server"></asp:TextBox>
<br /><hr /><br />
</asp:placeHolder>
<br />
<asp:LinkButton ID="UpdateButton" runat="server"
CausesValidation="True" CommandName="Update"
Text="Update">
</asp:LinkButton>
<asp:LinkButton ID="UpdateCancelButton" runat="server"
CausesValidation="False" CommandName="Cancel"
Text="Cancel">
</asp:LinkButton>
</EditItemTemplate>
<InsertItemTemplate>
name:
<asp:TextBox ID="nameTextBox" runat="server" Text='<%#
Bind("name") %>'>
</asp:TextBox><br />
<asp:LinkButton ID="InsertButton" runat="server"
CausesValidation="True" CommandName="Insert"
Text="Insert">
</asp:LinkButton>
<asp:LinkButton ID="InsertCancelButton" runat="server"
CausesValidation="False" CommandName="Cancel"
Text="Cancel">
</asp:LinkButton>
</InsertItemTemplate>
<ItemTemplate>
name:
<asp:Label ID="nameLabel" runat="server" Text='<%#
Bind("name") %>'></asp:Label><br />
id:
<asp:Label ID="idLabel" runat="server" Text='<%# Eval("id")
%>'></asp:Label><br />
<asp:LinkButton ID="EditButton" runat="server"
CausesValidation="False" CommandName="Edit"
Text="Edit">
</asp:LinkButton>
<asp:LinkButton ID="DeleteButton" runat="server"
CausesValidation="False" CommandName="Delete"
Text="Delete">
</asp:LinkButton>
<asp:LinkButton ID="NewButton" runat="server"
CausesValidation="False" CommandName="New"
Text="New">
</asp:LinkButton>
</ItemTemplate>
</asp:FormView>
</form>
=========================

=========code behind===============
public partial class subdir_FormViewPage : System.Web.UI.Page
{
private bool _setEdit = false;


protected void Page_Load(object sender, EventArgs e)
{

}


protected void FormView1_PreRender(object sender, EventArgs e)
{
if (_setEdit == true)
{
FormView1.ChangeMode(FormViewMode.Edit);
}


if (FormView1.CurrentMode == FormViewMode.Edit)
{
if (DropDownList1.SelectedValue == "ccc")
{
FormView1.FindControl("PlaceHolder1").Visible = true;
}
else
{
FormView1.FindControl("PlaceHolder1").Visible = false;
}

}
}
protected void FormView1_ItemUpdating(object sender,
FormViewUpdateEventArgs e)
{
PlaceHolder holder = FormView1.FindControl("PlaceHolder1") as
PlaceHolder;
TextBox txtInput = holder.FindControl("txtInput") as TextBox;

if (holder.Visible == true && txtInput != null)
{
Response.Write("<br/>additional input: " + txtInput.Text);
}
}
protected void FormView1_ItemUpdated(object sender,
FormViewUpdatedEventArgs e)
{
_setEdit = true;

}
}

============================

Hope this helps.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top