SelectedIndex Value Reported Incorrectly

  • Thread starter Nathan Sokalski
  • Start date
N

Nathan Sokalski

I am writing a User Control that uses 3 DropDownLists. When I attempt to
access the SelectedIndex property it incorrectly reports the value selected
by the user. Why is this? Here is my code, thanks:


Public Class DatePicker
Inherits System.Web.UI.UserControl

#Region " Web Form Designer Generated Code "

'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
End Sub
Protected WithEvents ddlMonth As System.Web.UI.WebControls.DropDownList
Protected WithEvents ddlDate As System.Web.UI.WebControls.DropDownList
Protected WithEvents ddlYear As System.Web.UI.WebControls.DropDownList

'NOTE: The following placeholder declaration is required by the Web Form
Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object

Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region

Public Property SelectedDate() As Date
Get
Return CDate(ViewState("datevalue"))
End Get
Set(ByVal Value As Date)
ViewState("datevalue") = Value
ViewState("startyear") =
Math.Min(CDate(ViewState("datevalue")).Year, CInt(ViewState("startyear")))
ViewState("stopyear") =
Math.Max(CDate(ViewState("datevalue")).Year, CInt(ViewState("stopyear")))
Me.CreateLists()
End Set
End Property
Public Property FirstYear() As Integer
Get
Return CInt(ViewState("startyear"))
End Get
Set(ByVal Value As Integer)
If Value <= CDate(ViewState("datevalue")).Year AndAlso Value >=
1 Then
ViewState("startyear") = Value
Me.CreateLists()
End If
End Set
End Property
Public Property LastYear() As Integer
Get
Return CInt(ViewState("stopyear"))
End Get
Set(ByVal Value As Integer)
If Value >= CDate(ViewState("datevalue")).Year AndAlso Value <=
9999 Then
ViewState("stopyear") = Value
Me.CreateLists()
End If
End Set
End Property

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
If Not IsPostBack() Then
ViewState.Add("datevalue", Date.Today)
ViewState.Add("startyear", 1950)
ViewState.Add("stopyear", 2050)
For i As Integer = 1 To 12
ddlMonth.Items.Add(New
ListItem(System.Globalization.DateTimeFormatInfo.CurrentInfo.GetMonthName(i),
CStr(i)))
Next
Me.CreateLists()
End If
End Sub

Private Sub CreateLists()
ddlYear.Items.Clear()
ddlDate.Items.Clear()
For j As Integer = CInt(ViewState("startyear")) To
CInt(ViewState("stopyear"))
ddlYear.Items.Add(CStr(j))
Next
For i As Integer = 1 To
Date.DaysInMonth(CDate(ViewState("datevalue")).Year,
CDate(ViewState("datevalue")).Month)
ddlDate.Items.Add(New ListItem(CStr(i) & " " &
System.Globalization.DateTimeFormatInfo.CurrentInfo.DayNames(New
Date(CDate(ViewState("datevalue")).Year,
CDate(ViewState("datevalue")).Month, i).DayOfWeek), CStr(i)))
Next
ddlMonth.SelectedIndex = CDate(ViewState("datevalue")).Month - 1
ddlYear.SelectedIndex = CDate(ViewState("datevalue")).Year -
CInt(ViewState("startyear"))
ddlDate.SelectedIndex = CDate(ViewState("datevalue")).Day - 1
End Sub

Private Sub DateChanged(ByVal sender As Object, ByVal e As
System.EventArgs) Handles ddlMonth.SelectedIndexChanged,
ddlYear.SelectedIndexChanged, ddlDate.SelectedIndexChanged
Dim selectedyear As Integer = ddlYear.SelectedIndex +
CInt(ViewState("startyear"))
Dim selectedmonth As Integer = ddlMonth.SelectedIndex + 1
Dim selectedday As Integer = ddlDate.SelectedIndex + 1
ViewState("datevalue") = New Date(selectedyear, selectedmonth,
Math.Min(Date.DaysInMonth(selectedyear, selectedmonth), selectedday))
Me.CreateLists()
End Sub
End Class




<%@ Control Language="vb" AutoEventWireup="false"
Codebehind="DatePicker.ascx.vb" Inherits="WebApplication1.DatePicker"
TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
<asp:dropdownlist id="ddlMonth" AutoPostBack="True"
runat="server"></asp:dropdownlist>
<asp:dropdownlist id="ddlDate" AutoPostBack="True"
runat="server"></asp:dropdownlist>
<asp:dropdownlist id="ddlYear" AutoPostBack="True"
runat="server"></asp:dropdownlist>
 
G

Guest

Hi Nathan,

Each time when page posts back, it reinitializes DropDownLists. Hence you
never get value from user selected.

HTH

Elton Wang
 
N

Nathan Sokalski

If you never get the value from the control, what is it's purpose? I know
there must be some way to get the SelectedIndex, I have done it plenty of
times in code I have written with pages, I am just having trouble doing it
with a User Control. The control was not invented just to look pretty, I
know there is some way to get the SelectedIndex.
 
K

Kevin Spencer

The problem is, you're re-initializing the drop-downs with each Page_Load.

The Page_Load method is calling a method that re-initializes the Drop-down
lists, and sets their SelectedIndex to -1. You only need to re-initialize
them if their contents need to change. They have ViewState to persist their
state across PostBacks.

If you ever DO need to re-initialize them, you should get their
SelectedIndex FROM ViewState prior to re-initializing them, and set it back
(if necessary) afterwards. But there is no need to re-create their contents
with each PostBack.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Big things are made up of
lots of little things.
 
N

Nathan Sokalski

What code do I have to remove to stop the reinitialization? I'm having
trouble figuring out where exactly the reinitialization is happening. I was
looking at a book recently, and it sounded a little to me (although I've
never written controls that store data before, so you'd know better than me)
like I might have to implement the IPostBackDataHandler.LoadPostData
function? However, all the examples I saw were with controls that only
contained one control, so I wouldn't know how to determine which of my DDLs
I was getting the data from. Is this implementation necessary for me to do,
or is what the DDLs I use sufficient and I just need to know how to avoid
the reinitialization? Thanks.
 
E

Elton Wang

Hi Nathan,



Actually I was wrong. You did have:



If Not IsPostback Then

CreateLists



to initialize ddls only in the first loading.



What I can suggest is you put breakpoints in both Page_Load and data process
methods and put SelectedIndex in watch winder. Then run it step by step to
see what happens. Since ddls are in an usercontrol, there is maybe something
unusual.



HTH
 
N

Nathan Sokalski

I think that did help. I propably overused some of the information I kept in
the Control. The problem was in the Set accessor functions for FirstYear and
LastYear when they called CreateLists(), once I removed them and changed one
place to using SelectedValue converted to an integer rather than calculating
from the SelectedIndex, I think it's good now. I think I never anticipated
before how often the accessor functions are called. Thanks.
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top