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.
Related
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
I have a database and a bound Listview with dynamically created controls. I have been attempting to find a way to capture the new value using markup as
<asp:ListView ID="ListView1" runat="server" DataSourceID="SqlDataSource1" DataKeyNames="ID" OnItemUpdating="ListView1_ItemUpdating">
and code behind as
Protected Sub ListView1_ItemUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewUpdateEventArgs) Handles ListView1.ItemUpdating
Dim capString As String = String.Empty
capString = e.NewValues
End Sub
This fails with the error Unable to cast object of type 'System.Collections.Specialized.OrderedDictionary' to type 'System.String'
I'm hoping someone could help me identify either a better way to accomplish capturing this data, or if it is possible to cast this data and how to do it in code.
Try
Dim capString As String = String.Empty
capString = e.NewValues(1) As String
Substitute 1 with an appropriate index for your capString.
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.
I have two aspx pages the first page has a textbox and the second aspx page has one textbox
In the second Page I am giving value to the text box by generating a session and giving that session ID to the textbox on the samepage
Now I need to retrieve back that session ID from the textbox and display it in first aspx page textbox which is not happening and not getting any error.
Here is my code for the first aspx page:
<asp:TextBox ID="CopySession" runat="server"></asp:TextBox>
This is my code for displaying the retrieved Session ID:
If IsPostBack Then
Dim text1 As TextBox = Me.PreviousPage.FindControl("SessionValue")
CopySession.Text = text1.Text
End If
This is my second aspx page:
<asp:TextBox ID="SessionValue" runat="server"></asp:TextBox>
This is my code behind for second aspx page:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Session("ID") Is Nothing Then
Session("ID") = Guid.NewGuid.ToString
SessionValue.Text = Session("ID")
End If
End Sub
Its quite simple just type cast it with previous page like following
(Me.PreviousPage as yourPageClass).SessionValue.Text
or use this on first page
<%# PreviousPageType VirtualPath="~/SecondPage.aspx" %>
and better way is
internal function TextBoxText() as string
return SessionValue.Text
end function
and get it on page one
currentPageTextbox.Text = Page.PrevousPage.TextBoxText
If you put it Session, just retrieve it. On Page_Load of your first page, do:
Dim sessionID As String = TryCast(Session("ID"), String)
If Not String.IsNullOrEmpty(sessionID) Then
SessionValue.Text = sessionID
End If
Am also looking around the same scenario and I found this URL as useful to me.
Am sharing this to you.. Exploring Session in ASP.Net
Refer this too
How can I access Session vars from Base class in ASP.Net?
ASP.Net MVC: How do you access the session from a different project within the solution?
The Repeater control in the following test case contains two runat="server" DIVs. Each one of them gets a TextBox appened to them through the ItemCreated event of the Repeater. Both of the have AutoPostBack=True, and TextChanged event wired to txt_TextChanged. However, only the TextBox from the first level properly points to the event on the postBack of the page. The second level TextBox also causes the postBack to occur, but its value does not persist in the VIEWSTATE as well as the event does not fire.
Here's a direct link to the test case in a .zip file (uploaded to my personal website), as well as all the code needed. The project is built in VS2010 using .NET Framework 4, but the problem also exists in 1.1, 2, and 3.5.
Anybody has any ideas on what is wrong and how to make this work?
ASPX
<asp:Repeater ID="rep" runat="server">
<ItemTemplate>
<!-- first level works -->
<div id="divOutside" runat="server">
<!-- second level doesn't work -->
<div id="divInside" runat="server"></div>
</div>
</ItemTemplate>
</asp:Repeater>
Code-Behind
Public Class WebForm1
Inherits System.Web.UI.Page
Private Sub WebForm1_Init(sender As Object, e As System.EventArgs) Handles Me.Init
If Not IsPostBack Then
Dim Table As New DataTable()
Table.Columns.Add("Column1")
Dim Row As DataRow = Table.NewRow()
Row("Column1") = ""
Table.Rows.Add(Row)
rep.DataSource = Table
rep.DataBind()
End If
End Sub
Private Sub repTest_ItemCreated(sender As Object, e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rep.ItemCreated
' outside
Dim divOutside As HtmlGenericControl = DirectCast(e.Item.FindControl("divOutside"), HtmlGenericControl)
Dim txtInput As New TextBox
With txtInput
.ID = "txtInputOutside"
.AutoPostBack = True
.Text = "Event gets called, value persists accross postBack."
.Width = 400
End With
AddHandler txtInput.TextChanged, AddressOf txt_TextChanged
divOutside.Controls.Add(txtInput)
' inside
Dim divInside As HtmlGenericControl = DirectCast(e.Item.FindControl("divInside"), HtmlGenericControl)
txtInput = New TextBox
With txtInput
.ID = "txtInputInside"
.AutoPostBack = True
.Text = "Event NOT called, value is lost during postBack."
.Width = 400
End With
AddHandler txtInput.TextChanged, AddressOf txt_TextChanged
divInside.Controls.Add(txtInput)
End Sub
Protected Sub txt_TextChanged(sender As Object, e As EventArgs)
End Sub
End Class
Is there any reason why the textboxes have to be added to the divs dynamically? why not just put them in the aspx page with the repeater then on itemdatabound enable/disable or do whatever you need to do. That should work fine.
By the way, if you were to use panels instead of divs your on the fly approach will work.
Here's a link to Microsoft Connect, where I reported this is an official bug:
https://connect.microsoft.com/VisualStudio/feedback/details/652655/asp-net-bug-in-event-linking-of-2nd-level-dynamic-controls
It contains 2 PARTIAL workarounds that work in the uploaded files section, if anybody is interested or encounters the same problem, as well as details to what I found in the Workarounds tab.
To keep it short, it is the order of getting references to the containers and the order the TextBoxes are appended to their appropriate containers which either causes the issue or works as expected.
But, not to forget the most important point, the only reason the first-level TextBox is there in the first place is to showcase what I want as functionality. If the first-level TextBox does not get appended at all, then both workarounds fail to provide any sort of fix. Please keep that in mind when reviewing that problem - finding a workaround that revolves around changing the order of the items is not an actual solution or a fully working workaround!
Thanks everyone for the input!