why does control remain visible after postback?

  • Thread starter Thread starter Dan
  • Start date Start date
D

Dan

Hi,

i experimented with postback and viewstate. With this code, there are 2
dropdownlists created, one visible and with AutoPostBack true, the other not
visible and no AutoPostBack, and one button . The first time, when i choose
value "b" of DD1, the second DD appears. That's normal.

Now, what i don't understand is when i further click on the button (causing
a postback), the second DD remains visible. Don't think i don't want it. I
just don't uderstand.

After clicking the button, I thought the code would start from the very
begin, so setting DD2 again on not visible. And because the first DD1 has
not changed its selectedvalue, the procedure dropd changing DD2 into visible
will not be executed. So DD2 should stay invisible. But it's not.

Can somebody explain what's wrong in my way of thinking?
Thanks
Dan


Imports System.Collections.Generic
Partial Class _Default
Inherits System.Web.UI.Page
Friend dds As New List(Of DropDownList)

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.PreInit
Dim dd1, dd2 As DropDownList
Dim z1, z2 As ListItem
Dim lit As LiteralControl
If Not IsPostBack Then
dd1 = New DropDownList
dd1.ID = "dd1"
dd1.AutoPostBack = True
z1 = New ListItem("a", "a")
dd1.Items.Add(z1)
z1 = New ListItem("b", "b")
dd1.Items.Add(z1)

dd2 = New DropDownList
dd2.ID = "dd2"
dd2.Visible = "false"
z2 = New ListItem("a", "a")
dd2.Items.Add(z2)
z2 = New ListItem("b", "b")
dd2.Items.Add(z2)

dds.Add(dd1)
dds.Add(dd2)
form1.Controls.Add(dd1)
form1.Controls.Add(dd2)
Session("dds") = dds
Else
dds = CType(Session("dds"), List(Of DropDownList))
For Each d As DropDownList In dds
form1.Controls.Add(d)
Next
End If

Dim bt2 As New Button
form1.Controls.Add(bt2)
AddHandler bt2.Click, AddressOf submit_Click

For Each d As DropDownList In dds
AddHandler d.SelectedIndexChanged, AddressOf dropd
Next
End Sub

Protected Sub dropd(ByVal sender As Object, ByVal e As System.EventArgs)
Dim dd As DropDownList = CType(sender, DropDownList)
Session("sv" & dd.ID) = dd.SelectedValue

If dd.ID = "dd1" And dd.SelectedValue = "b" Then
FindControl("dd2").Visible = True
ElseIf dd.ID = "dd1" And Not dd.SelectedValue = "b" Then
FindControl("dd2").Visible = False
End If
End Sub

Protected Sub submit_Click(ByVal sender As Object, ByVal e As
System.EventArgs)

End Sub
End Class
 
Dan said:
Hi,

i experimented with postback and viewstate. With this code, there are 2
dropdownlists created, one visible and with AutoPostBack true, the other
not visible and no AutoPostBack, and one button . The first time, when i
choose value "b" of DD1, the second DD appears. That's normal.

Now, what i don't understand is when i further click on the button
(causing a postback), the second DD remains visible. Don't think i don't
want it. I just don't uderstand.

After clicking the button, I thought the code would start from the very
begin, so setting DD2 again on not visible. And because the first DD1 has
not changed its selectedvalue, the procedure dropd changing DD2 into
visible will not be executed. So DD2 should stay invisible. But it's not.

Can somebody explain what's wrong in my way of thinking?
Thanks
Dan


Imports System.Collections.Generic
Partial Class _Default
Inherits System.Web.UI.Page
Friend dds As New List(Of DropDownList)

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.PreInit
Dim dd1, dd2 As DropDownList
Dim z1, z2 As ListItem
Dim lit As LiteralControl
If Not IsPostBack Then
dd1 = New DropDownList
dd1.ID = "dd1"
dd1.AutoPostBack = True
z1 = New ListItem("a", "a")
dd1.Items.Add(z1)
z1 = New ListItem("b", "b")
dd1.Items.Add(z1)

dd2 = New DropDownList
dd2.ID = "dd2"
dd2.Visible = "false"
z2 = New ListItem("a", "a")
dd2.Items.Add(z2)
z2 = New ListItem("b", "b")
dd2.Items.Add(z2)

dds.Add(dd1)
dds.Add(dd2)
form1.Controls.Add(dd1)
form1.Controls.Add(dd2)
Session("dds") = dds
Else
dds = CType(Session("dds"), List(Of DropDownList))
For Each d As DropDownList In dds
form1.Controls.Add(d)
Next
End If

Dim bt2 As New Button
form1.Controls.Add(bt2)
AddHandler bt2.Click, AddressOf submit_Click

For Each d As DropDownList In dds
AddHandler d.SelectedIndexChanged, AddressOf dropd
Next
End Sub

Protected Sub dropd(ByVal sender As Object, ByVal e As
System.EventArgs)
Dim dd As DropDownList = CType(sender, DropDownList)
Session("sv" & dd.ID) = dd.SelectedValue

If dd.ID = "dd1" And dd.SelectedValue = "b" Then
FindControl("dd2").Visible = True
ElseIf dd.ID = "dd1" And Not dd.SelectedValue = "b" Then
FindControl("dd2").Visible = False
End If
End Sub

Protected Sub submit_Click(ByVal sender As Object, ByVal e As
System.EventArgs)

End Sub
End Class
The ViewState field maintains this sort of information, it then recreates
the controls after postback based on their previous state.
 
Hi, thanks for replying.

I put the property EnableViewState="False"
but it makes no diffrerence: DD2 is still visible after clicking the button
....

Why?
 
Joe?


Dan said:
Hi, thanks for replying.

I put the property EnableViewState="False"
but it makes no diffrerence: DD2 is still visible after clicking the
button ...

Why?
 
Dan said:
Joe?


Dan said:
Hi, thanks for replying.

I put the property EnableViewState="False"
but it makes no diffrerence: DD2 is still visible after clicking the
button ...

Why?
I tried to duplicate the situation but the second dropdown is not visible
after postback. The code is here:

TestViewState.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Test ViewState</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DropDownList ID="ddl1" runat="server" AutoPostBack="True"
Height="26px"
onselectedindexchanged="ddl1_SelectedIndexChanged" Width="100px">
<asp:ListItem Selected="True">a</asp:ListItem>
<asp:ListItem>b</asp:ListItem>
<asp:ListItem>c</asp:ListItem>
</asp:DropDownList>&nbsp;
<asp:DropDownList ID="ddl2" runat="server" EnableViewState="False"
Height="31px" Visible="False" Width="100px">
<asp:ListItem Selected="True">1</asp:ListItem>
<asp:ListItem>2</asp:ListItem>
<asp:ListItem>3</asp:ListItem>
</asp:DropDownList>&nbsp;<asp:Button ID="cmd1" runat="server"
Text="Postback" />
</div>
</form>
</body>
</html>


TestViewState.aspx.cs
using System;

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

}
protected void ddl1_SelectedIndexChanged(object sender, EventArgs e)
{
if (ddl1.SelectedValue.ToString() == "b")
ddl2.Visible = true;
else
ddl2.Visible = false;
}
}
 
Thanks again,

but there is a big difference between your code and mine: you define the
dropdownlists in the aspx file, i define everything in code-behind.

I certify that with this code below as it is, when both DDLs are visible and
when you then click on the submit button, both DDL remains visible.
And i tried with EnableViewState="true" and with EnableViewState="false".

Just copy and paste it in your IIS and try.

So i have still the same question: what makes that DDL remaining visible?

Imports System.Collections.Generic
Partial Class _Default
Inherits System.Web.UI.Page
Friend dds As New List(Of DropDownList)

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.PreInit
Dim dd1, dd2 As DropDownList
Dim z1, z2 As ListItem
If Not IsPostBack Then
dd1 = New DropDownList
dd1.ID = "dd1"
dd1.AutoPostBack = True
z1 = New ListItem("a", "a")
dd1.Items.Add(z1)
z1 = New ListItem("b", "b")
dd1.Items.Add(z1)

dd2 = New DropDownList
dd2.ID = "dd2"
dd2.Visible = "false"
z2 = New ListItem("a", "a")
dd2.Items.Add(z2)
z2 = New ListItem("b", "b")
dd2.Items.Add(z2)

dds.Add(dd1)
dds.Add(dd2)
form1.Controls.Add(dd1)
form1.Controls.Add(dd2)
Session("dds") = dds
Else
dds = CType(Session("dds"), List(Of DropDownList))
For Each d As DropDownList In dds
form1.Controls.Add(d)
Next
End If

Dim bt2 As New Button
form1.Controls.Add(bt2)
AddHandler bt2.Click, AddressOf submit_Click

For Each d As DropDownList In dds
AddHandler d.SelectedIndexChanged, AddressOf dropd
Next
End Sub

Protected Sub dropd(ByVal sender As Object, ByVal e As System.EventArgs)
Dim dd As DropDownList = CType(sender, DropDownList)
Session("sv" & dd.ID) = dd.SelectedValue

If dd.ID = "dd1" And dd.SelectedValue = "b" Then
FindControl("dd2").Visible = True
ElseIf dd.ID = "dd1" And Not dd.SelectedValue = "b" Then
FindControl("dd2").Visible = False
End If
End Sub

Protected Sub submit_Click(ByVal sender As Object, ByVal e As
System.EventArgs)
End Sub
End Class

----------------------------------------------------------------------------
 
Dan said:
Thanks again,

but there is a big difference between your code and mine: you define the
dropdownlists in the aspx file, i define everything in code-behind.

I certify that with this code below as it is, when both DDLs are visible
and when you then click on the submit button, both DDL remains visible.
And i tried with EnableViewState="true" and with EnableViewState="false".

Just copy and paste it in your IIS and try.

So i have still the same question: what makes that DDL remaining visible?

Imports System.Collections.Generic
Partial Class _Default
Inherits System.Web.UI.Page
Friend dds As New List(Of DropDownList)

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.PreInit
Dim dd1, dd2 As DropDownList
Dim z1, z2 As ListItem
If Not IsPostBack Then
dd1 = New DropDownList
dd1.ID = "dd1"
dd1.AutoPostBack = True
z1 = New ListItem("a", "a")
dd1.Items.Add(z1)
z1 = New ListItem("b", "b")
dd1.Items.Add(z1)

dd2 = New DropDownList
dd2.ID = "dd2"
dd2.Visible = "false"
z2 = New ListItem("a", "a")
dd2.Items.Add(z2)
z2 = New ListItem("b", "b")
dd2.Items.Add(z2)

dds.Add(dd1)
dds.Add(dd2)
form1.Controls.Add(dd1)
form1.Controls.Add(dd2)
Session("dds") = dds
Else
dds = CType(Session("dds"), List(Of DropDownList))
For Each d As DropDownList In dds
form1.Controls.Add(d)
Next
End If

Dim bt2 As New Button
form1.Controls.Add(bt2)
AddHandler bt2.Click, AddressOf submit_Click

For Each d As DropDownList In dds
AddHandler d.SelectedIndexChanged, AddressOf dropd
Next
End Sub

Protected Sub dropd(ByVal sender As Object, ByVal e As
System.EventArgs)
Dim dd As DropDownList = CType(sender, DropDownList)
Session("sv" & dd.ID) = dd.SelectedValue

If dd.ID = "dd1" And dd.SelectedValue = "b" Then
FindControl("dd2").Visible = True
ElseIf dd.ID = "dd1" And Not dd.SelectedValue = "b" Then
FindControl("dd2").Visible = False
End If
End Sub

Protected Sub submit_Click(ByVal sender As Object, ByVal e As
System.EventArgs)
End Sub
End Class

You are not declaring the second drop down as AutoPostBack = True

Also if you turn Strict On ... (always a good thing to do to catch
problems), when you do you will see that you are trying to set a boolean to
"false". Those are the types of things that will bite you in the end.

Hope this helps
LS
 
The second DDL has not its property AutoPostBack set on true, indeed, but
thus has nothing to do with the fact DD2 remains visibel after clicking the
submit button.

I tried the code with Strict on and off, but this makes no difference here
....

So, i still have the same question unsolved.
A great mystery in ASP.NET land or something stupid nobody sees?
 
Dan,

Out of interest, why are you defining all the controls programatically?
Wouldn't it be much easier just to put them on the ASPX page and
show/hide them if you need to using the "visible" property?

It seems a very strange and complicated way to do what you're doing, but
I presume you have a good reason? :)

Nick..
 
Yes i have.

I don't know in advance how many dropdownlists i will need. This is only an
simple example in order to try to find the reason.
But i finally found it. It's due to Session("dds") = dds which gets the new
values and then put them back in the form.
 
Back
Top