Cannot update asp:RangeValidator contained in ListView EditItemTemplate - asp.net

I am struggling to get an asp:RangeValidator to change the minimum and maximum value programmatically. Unfortunately I am seeing a console error message stating:
'Uncaught Sys.WebForms.PageRequestManagerServerErrorException: Sys.WebForms.PageRequestManagerServerErrorException: The value '' of the MaximumValue property of 'rvDateFrom' cannot be converted to type 'Date'.
My code can be seen below. The calendar is contained in the EditItemTemplate of a ListView, which is contained in an UpdatePanel.
<ewc:CalendarPopup ID="cpDateFrom" runat="server" SelectedDate='<%# Bind("DateFrom")%>' CssClass="date"></ewc:CalendarPopup>
<asp:RangeValidator ID="rvDateFrom" runat="server" ControlToValidate="cpDateFrom" Type="Date" ErrorMessage="Invalid"></asp:RangeValidator>
The code behind is as follows:
Private Sub lvRangeValidatorTest_ItemEditing(sender As Object, e As ListViewEditEventArgs) Handles lvRangeValidator.ItemEditing
lvRangeValidator.EditIndex = e.NewEditIndex
DataBind()
Dim rvDateFrom As RangeValidator = CType(lvRangeValidatorTest.Items(e.NewEditIndex).FindControl("rvDateFrom"), RangeValidator
rvDateFrom.MinimumValue = "01/01/1900"
rvDateFrom.MaximumValue = "01/01/2020"
End Sub
The RangeValidator is found, as intentionally entering the incorrect name throws an instance of an object error, but it does not seem to actually update the RangeValidator. Thus leaving the minimum and maximum values blank.
Thoughts?
Many thanks.

After some more research and unsuccessfully trying to use the ItemDataBound event, I successfully used the DataBound event.
lvRangeValidatorTest_DataBound(sender As Object, e As EventArgs) Handles lvRangeValidatorTest.DataBound
If lvRangeValidatorTest.EditItem IsNot Nothing Then
Dim rvDateFrom As RangeValidator = CType(lvRangeValidator.EditItem.FindControl("rvDateFrom"), RangeValidator)
rvDateFrom.MinimumValue = "01/01/1900"
rvDateFrom.MaximumValue = "01/01/2020"
End If
End Sub

Related

VB.NET Obj Ref not set in datetime

I've seen similar questions through extensive 'google-ing' but none have been able to sort this issue out, the error I'm getting from VS13 is below:
An exception of type 'System.NullReferenceException' occurred in
my.dll but was not handled in user code. Additional information:
Object reference not set to an instance of an object.
Simply put I want a default date value to populate within the calendar textbox so the user doesn't have to choose a date, or if they forget etc it'll put the system time in.
I've tried converting toString etc and I get the same error.
Any help would be gratefully received.
Thanks in advance.
Code behind:
Public Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Dim SrtDateTxt As New TextBox
SrtDateTxt = ListView1.FindControl("StartDateTextBox")
SrtDateTxt.Text = DateTime.Now
End If
End Sub
And the aspx that the above code behind relates to:
<asp:TextBox ID="StartDateTextBox" runat="server" Text='<%# Bind("StartDate") %>' Width="150px"/>
<act:CalendarExtender ID="CalendarExtender1" runat="server" TargetControlID="StartDateTextBox" Format="yyyy-MM-dd"></act:CalendarExtender>
First i want to suggest to change Option Strict to "On" in your project's settings. That won't you prevent from compiler errors but from nasty runtime errors. Fixing the compiler errors will teach you much about the types in the .NET framework.
Then for example this will not compile anymore:
SrtDateTxt.Text = DateTime.Now
You need to assign a string instead of a Date:
SrtDateTxt.Text = DateTime.Now.ToString() ' or ToShortDateString()
Next, this will not prevent you from a NullRefernceException:
Dim SrtDateTxt As New TextBox
If you assign another value to this variable one line afterwards:
SrtDateTxt = ListView1.FindControl("StartDateTextBox")
So i assume that SrtDateTxt is Nothing because there is no control with that ID in the ListView but in one of it's ListViewItems(which are different NamingContainers).
Therefore you get the exception at the next line when you try to access a property
SrtDateTxt.Text = DateTime.Now ' at .Text
A ListView is meant to be used for multiple items. So you need to use the correct ListViewItem.
For Each item As ListViewItem In ListView1.Items
Dim StartDateTextBox = DirectCast(item.FindControl("StartDateTextBox"), TextBox)
' ... '
Next
This loops all items, i don't know if that is what you want to do.

Setting focus to a textbox within an UpdatePanel

I have four textboxes within an UpdatePanel, and AutoPostBack is set to True for all of them. When the user enters a value and hits Enter, I want the cursor to move to the next textbox automatically. When I don't have the controls in an UpdatePanel, the standard textbox.focus method works fine.
I found some code here that led me to create this:
Protected Sub txtField_TextChanged(ByVal sender As Object, ByVal e As EventArgs) Handles txtField1.TextChanged,
txtField2.TextChanged, txtField3.TextChanged
'Based on the textbox where data was changed, move the cursor to the next field.
Try
Dim sm As ScriptManager = ScriptManager.GetCurrent(Me)
'As multiple textboxes fire this same event, determine which textbox triggered this.
Dim MyTextbox As TextBox = TryCast(sender, TextBox)
Select Case MyTextbox.ID.ToString
Case "txtField1"
sm.SetFocus(txtField2)
Case "txtField2"
sm.SetFocus(txtField3)
Case "txtField3"
sm.SetFocus(txtField4)
End Select
Catch ex As Exception
lblError.Text = "Error in [txtField_TextChanged]: " & ex.Message
End Try
End Sub
What is really strange is that this works ONCE on whatever field I try first. After that, the event is fired, but the focus does not change. Is there something additional I need to to for subsequent calls?
I would appreciate any suggestions. Thank you!
Try setting the EnablePartialRendering property of the ScriptManager to false, like so:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="false"></asp:ScriptManager>
I hope this helps! Good luck, and happy coding :)

PagedDataSource not showing data in subsequent pages

It's probably something small, but I haven't been figure out why the following isn't working completely. The first time the user submits the search, the first page of search results show up properly. However, when the user tries to navigate by using the Previous and Next Page buttons, the repeater doesn't show the appropriate data from the DataTable.
search.aspx
<asp:Repeater ID="rptSearchResults" runat="server" OnItemDataBound="rptSearchResults_ItemDataBound">
<ItemTemplate>
<div>
<asp:Literal ID="ltlCustName" runat="server" />
</div>
</ItemTemplate>
</asp:Repeater>
search.aspx.vb
Public dtCustomers As DataTable = New DataTable()
Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs) Handles Me.Load
' Check to see if this is the first time postback-ing to itself.
blnFirstPostBack = (Request.Form("firstpb") = "1")
' When the page first loads, show the search form with search options.
If Not Page.IsPostBack Then
Session("StoredDT") = Nothing
ShowSearchForm()
' Once the form is submitted, show the search results.
Else
Response.Write("DEBUG: Get Data")
If blnFirstPostBack Then
GatherFormData()
dtCustomers = BuildDT()
Session("StoredDT") = dtCustomers
BindData()
ElseIf Not Session("StoredDT") Is Nothing Then
dtCustomers = Session("StoredDT")
End If
End If
End Sub
Sub BindData()
Response.Write("DEBUG: Bind Data")
' At this point, I've checked that the dtCustomers is showing the proper data (e.g., grabbing from session when appropriate).
Dim objPDS As PagedDataSource = New PagedDataSource()
objPDS.DataSource = dtCustomers.DefaultView
objPDS.AllowPaging = True
objPDS.PageSize = intNumPerPage
' I've checked that Me.ViewState("_CurrentPage") gets updated to the correct page.
objPDS.CurrentPageIndex = Me.ViewState("_CurrentPage")
rptSearchResults.DataSource = objPDS
' I'm not sure if the error is here but although the dtCustomers is the proper data, the PagedDataSource and the binding here doesn't seem to play nice.
Call rptSearchResults.DataBind()
End Sub
' Subroutine called when the previous page button is pressed.
Sub GoToPrevPage()
Response.Write("DEBUG: Prev Page")
' Set viewstate variable to the previous page.
Me.ViewState("_CurrentPage") -= 1
BindData()
End Sub
' Subroutine called when the next page button is pressed.
Sub GoToNextPage()
Response.Write("DEBUG: Next Page")
' Set viewstate variable to the next page.
Me.ViewState("_CurrentPage") += 1
BindData()
End Sub
Protected Sub rptSearchResults_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptSearchResults.ItemDataBound
Dim item As RepeaterItem = e.Item
Dim strCustName As String = ""
If (item.ItemType = ListItemType.Item) Or (item.ItemType = ListItemType.AlternatingItem) Then
strCustName = e.Item.DataItem("CustName")
Dim ltlCustName As Literal = CType(e.Item.FindControl("ltlCustName"), Literal)
ltlCustName.Text = strCustName
End If
End Sub
Sample Page 1 (shows proper data):
DEBUG: Get Data
DEBUG: Bind Data
Laurence Clinton
John Doe
Sean King
Jane Smith
Sample Page 2 (does not show proper data but shows enough spaces for the missing data):
DEBUG: Get Data
DEBUG: Next Page
DEBUG: Bind Data
[no name showing here 5]
[no name showing here 6]
[no name showing here 7]
[no name showing here 8]
Please excuse the abbreviated code but the actual code is massive so the simplification is to make it easier to get to the heart of the issue.
Let me know if any of that was unclear or if more code is required. Thanks in advance!
Update 2/19/2013:
So after fiddling with the code a bit, I think the error happens in the repeater subroutine. The original literal inside of the repeater works now. For some reason I don't think it worked before but it works fine now. The problem is when we go a step further using a custom control inside of the repeater subroutine. It seems that the information doesn't get passed into the control. The control gets called properly because supporting HTML found only within the control gets outputted properly but the customer information that we try to pass into the control doesn't get inside. Here is the modified code:
search.aspx
<asp:Repeater ID="rptSearchResults" runat="server" OnItemDataBound="rptSearchResults_ItemDataBound">
<ItemTemplate>
<div>
<asp:Literal ID="ltlCustName" runat="server" />
<Acme:CustInfo ID="AcmeCustInfo" runat="server" />
</div>
</ItemTemplate>
</asp:Repeater>
search.aspx.vb
Protected Sub rptSearchResults_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptSearchResults.ItemDataBound
Dim item As RepeaterItem = e.Item
Dim strCustName As String = ""
If (item.ItemType = ListItemType.Item) Or (item.ItemType = ListItemType.AlternatingItem) Then
strCustName = e.Item.DataItem("CustName")
' This literal properly shows the customer name on subsequent pages so the customer name reaches this point properly.
Dim ltlCustName As Literal = CType(e.Item.FindControl("ltlCustName"), Literal)
ltlCustName.Text = strCustName
' This control gets called properly but strCustName doesn't
' get passed into the control. The control works fine for the
' first page but subsequent pages do not work. Also, the
' control works fine when PagedDataSource is not used.
Dim AcmeCustInfo As CustInfo = CType(e.Item.FindControl("AcmeCustInfo"), CustInfo)
AcmeCustInfo.CustName = strCustName
End If
End Sub
Per Request from Ann
Here is the code for CustInfo. Needless to say, a lot of the fluff has been stripped out to focus on the issue but if anything is missing that will be useful, please let me know and I'll update the example accordingly.
custinfo.ascx
<%# Control Language="VB" AutoEventWireup="false" CodeFile="CustInfo.ascx.vb" Inherits="CustInfo" %>
<div style="border: 1px solid black;">
<asp:Literal ID="ltlCustName" runat="server" />
</div>
custinfo.ascx.vb
Imports System
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.HtmlControls
Imports System.Configuration
Imports System.Data
Imports System.Data.SqlClient
Imports System.IO
Imports System.Web.HttpUtility
Partial Class CustInfo
Inherits System.Web.UI.UserControl
Private _CustName As String = ""
Public Property CustName() As String
Get
Return _CustName
End Get
Set(value As String)
_CustName = value
End Set
End Property
Public Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs) Handles Me.Load
Dim ltlCustName As Literal = CType(FindControl("ltlCustName"), Literal)
ltlCustName.Text = "<b>Name: " & CustName & "</b>"
End Sub
End Class
I'm not a PagedDataSource expert, but I've used user controls extensively.
You're setting the value of the literal in your CustInfo control in the Load subroutine. If I'm not mistaken, that's going to get called when the CustInfo control is created. That would happen before OnItemDataBound is called, so -- I think -- the Load subroutine will happen and the value of the literal be set (to an empty string) before you assign the value of the CustName property. To fix this, try setting the value of the literal later, such as in the PreRender subroutine.
It looks like you're binding on every postback, so the following shouldn't be an issue, but if you aren't, here are some thing that might affect you:
ItemDataBound only runs if you re-bind. If you have ViewState turned on for your repeater, the controls will be recreated on postback, and ItemCreated would run, but ItemDataBound wouldn't. So you'd never re-set your CustName property. And this would matter because ...
... your CustName property has a variable as a backing store: it isn't preserved in ViewState. So when the user control is recreated, the CustName property you previously set won't be there anymore: your literal's contents will be set to the empty string that is the default value of the CustName property.
Those two together would give exactly the behavior you've described. But since it looks like you do bind on every postback (eventually) that may not be the issue. I'm including it for completeness.

what is wrong in my this vb.net code

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim lab As Label = Me.GridView1.FindControl("Label1")
If TextBox2.Text = "7" Then
GridView1.SelectedRow.Cells(2).Text = "500"
Else
GridView1.SelectedRow.Cells(2).Text = "950"
End If
End Sub
The following error occurs : Object reference not set to an instance of an object.
You've got this code in your Page Load event, so it will run when the page is first loaded, and on every single postback. This probably isn't what you want.
I imagine that on the very first load, there isn't a selected row in your GridView, so GridView1.SelectedRow is going to be null. If this isn't null, then Cells or Cells(2) definitely will be. Trying to access a property on null is going to throw a NullReferenceException - "Object reference not set to an instance of an object".
As this MSDN example shows, you're probably better off accessing the SelectedRow property in an event handler for the SelectedIndexChanged event of the GridView.
Dim lab As Label = Me.GridView1.FindControl("Label1")
It doesn't look like you're doing anything with this label. Put a breakpoint on that line and see if it finds it. If it doesn't and you don't even use it, take the line out.
Also, check if textbox2 is valid whilst debugging.

ASP.NET get hidden value from list view on ItemCommand

I have LinkButton and HiddenField in a list view. I want to get the hidden value from HiddenField, so I can store it in Session and when a LinkButton is clicked it transfer the hidden value ( stored in Session) to another page. But I get this error message "Object reference not set to an instance of an object." Here's the function:
Protected Sub lvTimeSheet_ItemCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewCommandEventArgs) Handles lvTimeSheet.ItemCommand
Dim id As HiddenField = TryCast(e.Item.FindControl("hfTimeSheetId"), HiddenField)
Dim myId As String = id.Value.ToString
Session("myId") = myId
Server.Transfer("Destination.aspx")
End Sub
The mark-up
</asp:LinkButton><asp:HiddenField ID="hfTimeSheetId1" runat="server" Value='<%# Eval("hfTimeSheetId") %>' />
Every time the LinkButton is clicked, it causes error with above error message. Thank you for any input.
My guess would be that the FindControl isn't finding the hfTimeSheetId control within the row. Do you have it designated as a managed control (i.e. runat="server")?
Also, it might help if you provided the ASPX code to see how you're defining the controls.
The FindControl is returning null, hense the exception. Try changing it to:
Dim id As HiddenField = TryCast(e.Item.FindControl("hfTimeSheetId1"), HiddenField)

Resources