Populating a variable with DetailsView textbox data value - asp.net

When an ASP.Net DetailsView data is first displayed, can you tell me how to populate the variable shown in this coding?
I already tried this in the code-behind file but was shown an error that:
Object reference not set to an instance of an object.
This is the coding:
Protected Sub DetailsViewDetails_DataBound(sender As Object, e As EventArgs) Handles DetailsViewDetails.DataBound
Dim txtOriginalRegistrationFee As TextBox
If DetailsViewDetails.CurrentMode = DetailsViewMode.Edit Then
txtOriginalRegistrationFee = FindControl("TextBoxRegistrationFee")
If String.IsNullOrEmpty(txtOriginalRegistrationFee.Text) = False Then
MsgBox(txtOriginalRegistrationFee)
End If
End If
End Sub
This is from the aspx file:
<asp:TemplateField HeaderText="RegistrationFee" SortExpression="RegistrationFee">
<EditItemTemplate>
<asp:TextBox ID="TextBoxRegistrationFee" runat="server" Text='<%# Eval("RegistrationFee") %>'></asp:TextBox>
</EditItemTemplate>
<InsertItemTemplate>
<asp:TextBox ID="TextBoxRegistrationFee" runat="server" Text='<%# Bind("RegistrationFee") %>'></asp:TextBox>
</InsertItemTemplate>
<ItemTemplate>
<asp:Label ID="LabelRegistrationFee" runat="server" Text='<%# Bind("RegistrationFee", "{0:c}") %>'></asp:Label>
</ItemTemplate>
<ItemStyle ForeColor="Blue" />
</asp:TemplateField>
* Update *
I tried using this coding updated based on your help but still get the "Object reference not set to an instance of an object." error when clicking the edit button of the DetailsView.

The FindControl function needs a control to search otherwise it will be searching the page (or content) level controls.
Try
txtOriginalRegistrationFee = DetailsViewDetails.FindControl("TextBoxRegistrationFee")
By the way your line with the MsgBox function will not work either. MsgBox is for windows forms and will not work on the web. You must use javascript for that type of functionality. Plus, that function takes a string, not a control.

I don't work in VB so bear with me.... The template is only rendered if your details view is in insert mode.
Dim txtOriginalRegistrationFee As TextBox
If DetailsViewDetails.CurrentMode = DetailsViewMode.Insert Then
txtOriginalRegistrationFee = FindControl("TextBoxRegistrationFee")
If String.IsNullOrEmpty(txtOriginalRegistrationFee.Text) = False Then
MsgBox(txtOriginalRegistrationFee)
End If
End If

Related

How do I access a hyperlink control that's in a gridview from _RowEditing Sub?

I've run into a wall and could use some advice. I have a gridview that contains a "Details" hyperlink on each row. While I am in edit mode (inline), I want to disable the details link. I thought this would be simple, but I can't seem to make it work. I had assumed (wrongly) that I could do something like:
Dim lnkDetails As HyperLink = CType(e.Row.FindControl("lnkDetails"), HyperLink)
lnkDetails.Enabled = False
The problem here, as I found out, is the "e As GridViewEditEventArgs" part of my Sub doesn't include "Row".
Here is the relevant code:
Protected Sub gvCurRecords_RowEditing(ByVal sender As Object, ByVal e As GridViewEditEventArgs)
' Make the GridView control into edit mode for the selected row.
gvCurRecords.EditIndex = e.NewEditIndex
' Rebind the GridView control to show data in edit mode.
BindGridView()
' Hide the Add button.
lbtnAdd.Visible = False
End Sub
HTML (Only the relevant column):
<asp:GridView ID="gvCurRecords" CellPadding="4" DataSourceId="SqlDataSource1"
Autogeneratecolumns="false" AutoGenerateEditButton="true"
AutoGenerateDeleteButton="true" OnRowEditing="gvCurRecords_RowEditing"
OnRowCancelingEdit="gvCurRecords_RowCancelingEdit"
OnRowUpdating="gvCurRecords_RowUpdating" DataKeyNames="eventID"
OnRowDataBound="gvCurRecords_RowDataBound"
OnPageIndexChanging="gvCurRecords_PageIndexChanging" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="lnkDetails" runat="server" Text='Details' NavigateUrl='<%#FormatUrl(CInt(Eval("EventID")))%>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:Gridview>
Any help would be greatly appreciated. Thanks.
Use the edit template to define a label instead of a hyperlink:
<EditItemTemplate>
<asp:Label ID="lbDetails" runat="server" Text='something else' />
</EditItemTemplate>

ASP.Net 4.5 Model Binding Cascading Drop Downs Null Reference (web Forms)

I'm retrofitting an older web forms site with Model Binding using asp.net 4.5.
In a DetailsView I have a drop down list that allows selection of a particular 'client' and another that allows selection of a particular 'project' that belongs to that client. So the drop down for project has to be filtered on the client number and if the user changes the client selection, I want to filter the project list by client number.
I couldn't figure out how to get the SelectedIndexChanged method on the client ddl to fire the Select method for the Project, so I concluded the only way to do it was to filter the project ddl by client number in all cases. I am getting an error message when the client selection is made:
NullReferenceException was Unhandled by User Code
which point in my aspx directly to the ddl for Projects.
This is an abbreviated version of the details view, you can see both the clients ddl and the projects ddl (I am operating in Edit mode):
<asp:DetailsView ID="AdministratorDetailsView" runat="server" AutoGenerateRows="False"
DataKeyNames="AdministratorNumber" ItemType="BusinessLogic.Administrator"
Width="99%"
SelectMethod="AdministratorDetailsView_GetItem"
UpdateMethod="AdministratorDetailsView_UpdateItem"
DeleteMethod="AdministratorDetailsView_DeleteItem"
FieldHeaderStyle-Width="30%" EditRowStyle-Width="99%"
InsertRowStyle-Width="70%" RowStyle-Width="99%" CssClass="admin"
AutoGenerateDeleteButton="true" AutoGenerateEditButton="true" >
<Fields>
<asp:TemplateField HeaderText="AdministratorCode" SortExpression="AdministratorCode">
<EditItemTemplate>
<asp:Label ID="AdministratorCode" Text="<%# Item.AdministratorCode%>" runat="server" />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="AdministratorCode" Text="<%# Item.AdministratorCode%>" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ClientNumber" SortExpression="ClientNumber">
<EditItemTemplate>
<asp:DropDownList ID="ddClients" runat="server"
AutoPostBack="true"
DataTextField="ClientName" DataValueField="ClientNumber"
ItemType="BusinessLogic.Client"
SelectMethod="ddClients_GetList"
SelectedValue="<%# Item.ClientNumber%>"
OnSelectedIndexChanged="AdministratorDetailsView_ddlClients_SelectedIndexChanged"/>
</EditItemTemplate>
<ItemTemplate>
<asp:DropDownList ID="ddClients" runat="server" Enabled="false"
DataTextField="ClientName" DataValueField="ClientNumber"
ItemType="BusinessLogic.Client"
SelectMethod="ddClients_GetList"
SelectedValue="<%# Item.ClientNumber%>"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Projects" >
<EditItemTemplate>
<asp:DropDownList ID="ddProjects" runat="server" AutoPostBack="true"
DataTextField="ProjectName" DataValueField="ProjectNumber"
ItemType="BusinessLogic.Project"
SelectMethod="ddProjects_GetList"
SelectedValue="<%# Item.ProjectNumber%>" />
</EditItemTemplate>
<ItemTemplate>
<asp:DropDownList ID="ddProjects" runat="server" Enabled="false"
DataTextField="ProjectName" DataValueField="ProjectNumber"
ItemType="BusinessLogic.Project"
SelectMethod="ddProjects_GetList"
SelectedValue="<%# Item.ProjectNumber%>"/>
</ItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView>
There are two SelectMethods, one for each drop down list, and a selectedindexchaneged method for clients:
Public Function ddClients_GetList() As List(Of BusinessLogic.Client)
Dim special As New List(Of Client)
special = CurrentClient.ClientList() 'add whole list
Dim NullClient As New Client()
NullClient.Load(0)
NullClient.ClientName = "<-Not Selected-->"
special.Add(NullClient) 'Had to have a client with 0 in the list since most admins don't have anything but 0 inthis field
Return special
End Function
Public Function ddProjects_GetList(<Control("ddClients")> ByVal ClientNumber As Integer) As List(Of BusinessLogic.Project)
Dim special As New List(Of Project)
If ClientNumber = 0 Then
special = CurrentProject.ProjectList() 'add whole list, refine it if Clients Drop Down selected
Else
special = CurrentProject.ProjectList(ClientNumber) 'add whole list, refine it if Clients Drop Down selected
End If
Dim NullProject As New Project()
NullProject.Load(0)
NullProject.ProjectName = "<-Not Selected-->"
special.Add(NullProject) 'Had to have a Project with 0 in the list since most admins don't have anything but 0 inthis field
Return special
End Function
Protected Sub AdministratorDetailsView_ddlClients_SelectedIndexChanged(sender As Object, e As EventArgs)
Dim ddlProj As DropDownList
ddlProj = AdministratorDetailsView.FindControl("ddProjects")
ddlProj.ItemType = "BusinessLogic.Project"
ddlProj.DataBind()
End Sub
All is well until the user selects a different client which triggers the SelectIndexChanged event and then we get to the DataBind(), where we get the null exception (ddlProj is found).
Need some ideas on how to refresh the projects list based on the new client selection.
How do I force ddProjects to run its SelectMethod again, to avoid the null reference and reload the control?
Turns out this issue is not unique to ModelBinding, but is a General WebForms Issue.
You cannot have cascading dropdowns within another data control where they depend on each other unless you add a bit of code.
In my case, I was trying to bind both dropdowns to the underlying detailsview, and at the same time setting the selected values. Doesn't work because of timing. It seems right until you try to change the selection on the parent dropdown, and then you get null exception on the second because it is not yet loaded. It's all timing. If you try to work around it with saved values, it gets too messy.
My solution is, Bind another item to the underlying details view (you can make it hidden if you wish). Then add some code to keep it in sync with the actual value. DO NOT Bind SelectedValue on the secondary drop down , this is what causes the problem. Manage Selected Value in code using the added field.
<asp:DetailsView ID="AdministratorDetailsView" runat="server" AutoGenerateRows="False"
DataKeyNames="AdministratorNumber" ItemType="BusinessLogic.Administrator"
Width="99%" SelectMethod="AdministratorDetailsView_GetItem" UpdateMethod="AdministratorDetailsView_UpdateItem" DeleteMethod="AdministratorDetailsView_DeleteItem"
FieldHeaderStyle-Width="30%" EditRowStyle-Width="99%" InsertRowStyle-Width="70%" RowStyle-Width="99%" CssClass="admin" AutoGenerateDeleteButton="true" AutoGenerateEditButton="true"
>
<Fields>
<asp:TemplateField HeaderText="Client Name" SortExpression="ClientName">
<EditItemTemplate><asp:DropDownList ID="ddClients" runat="server" AutoPostBack="true" DataTextField="ClientName" DataValueField="ClientNumber" ItemType="BusinessLogic.Client" SelectMethod="ddClients_GetList" SelectedValue="<%# Item.ClientNumber%>" OnDataBound="ddClients_DataBound" OnSelectedIndexChanged="AdministratorDetailsView_ddlClients_SelectedIndexChanged" /> </EditItemTemplate>
<ItemTemplate><asp:DropDownList ID="ddClients" runat="server" Enabled="false" DataTextField="ClientName" DataValueField="ClientNumber" ItemType="BusinessLogic.Client" SelectMethod="ddClients_GetList" SelectedValue="<%# Item.ClientNumber%>"/></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="Project Number" >
<EditItemTemplate><asp:Label ID="ProjectNumberLabel" runat="server" Text="<%# BindItem.ProjectNumber%>"></asp:Label></EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Project Name" SortExpression="ProjectNumber">
<EditItemTemplate><asp:DropDownList ID="ddProjects" runat="server" AutoPostBack="true" DataTextField="ProjectName" DataValueField="ProjectNumber" ItemType="BusinessLogic.Project" SelectMethod="ddProjects_GetList" OnDataBound="ddProjects_DataBound" OnSelectedIndexChanged="ddProjects_SelectedIndexChanged" />
</EditItemTemplate>
<ItemTemplate><asp:DropDownList ID="ddProjects" runat="server" Enabled="false" DataTextField="ProjectName" DataValueField="ProjectNumber" ItemType="BusinessLogic.Project" SelectMethod="ddProjects_GetList" SelectedValue="<%# Item.ProjectNumber%>" />
</ItemTemplate>
</asp:TemplateField>
</asp:DetailsView>
And in the code behind, not how we set and get the value of the bound projectnumber:
Protected Sub AdministratorDetailsView_ddlClients_SelectedIndexChanged(sender As Object, e As EventArgs)
''If this selection changes we need to change some flags and perhaps theProject ddl
''This causes null exception for Project ddl, can't figure out how to get it to reload. Tried DataBind(), same effect as having a ValueProvider in the parameters to the Select
Dim ProjectNumberLabel As Label = AdministratorDetailsView.FindControl("ProjectNumberLabel")
ProjectNumberLabel.Text = "0" 'Synchronize to no selection
Dim ddProjects As New DropDownList
ddProjects = AdministratorDetailsView.FindControl("ddProjects") 'Have to use Find Control because ddl is buried in DetailsView
ddProjects.SelectedValue = 0 'Cause it to read Select an Item
ddProjects.DataBind() 'Rebinding it causes the SelectMethod to run.
End Sub
Protected Sub ddProjects_DataBound(sender As Object, e As EventArgs)
'Because of the problem with cascading references, we had to remove the SelectValue declaration from ddProjects.
'So we must make sure that once theddProjects is databound, it points to the selected value from the data
Dim ddlProjects As DropDownList
ddlProjects = AdministratorDetailsView.FindControl("ddProjects")
Dim ProjectNumberLabel As Label = AdministratorDetailsView.FindControl("ProjectNumberLabel")
ddlProjects.SelectedValue = CInt(ProjectNumberLabel.Text)
End Sub
Hope someone else sees this as useful. I couldn't find it anywhere.
Great posting, as I faced a similar conundrum and it made me think. I have done this before outside of the model-binding approach, and the solution is essentially the same, as described. I used a ListView, and added the method:
OnItemDataBound="lvWhatever_ItemDataBound"
to fire an event from which to go and get the relevant ID from another bound control in the list view data item:
if (e.Item.ItemType == ListViewItemType.DataItem)
{
// get the ID from from another control in this item record: lblItemID
ListViewDataItem lvdi = (ListViewDataItem)e.Item;
if (lvdi != null)
{
Label iID = (Label)lvdi.FindControl("lblItemID");
if (iID != null)
where lblItemID.Text contains the relevant ID. Then from that I can query to get the relevant list, and manually bind it to the DDL. Brilliant - thanks very much.

Using FindControl method of FormView within a Repeater

I need an advice how to correct my code. I am using FindControl method to find TextBox inside Repeater. This is my markup:
<asp:Repeater ID="Repeater1">
HERE ARE SOME OTHER DATA
<ItemTemplate>
<asp:FormView ID="FormViewAddComment" runat="server"
DataSourceID="SqlDataSourceInsertComments" DefaultMode="Insert"
OnItemInserted="FormViewAddComment_ItemInserted"
OnItemInserting="FormViewAddComment_ItemInserting">
<InsertItemTemplate>
<asp:TextBox ID="txtAddComment" runat="server" CssClass="textbox"
Text='<%# Bind("CommentText") %>' Width="200px" />
<asp:Button ID="btnAddComment" runat="server" CssClass="button"
Text="Comment" CommandName="Insert" CausesValidation="false"/>
</InsertItemTemplate>
</asp:FormView>
</ItemTemplate>
</asp:Repeater>
And this is my code behind:
Protected Sub FormViewAddComment_ItemInserting(sender As Object, e As FormViewInsertEventArgs)
Dim FormView As FormView = DirectCast(Repeater1.FindControl("FormViewAddComment"), FormView)
Dim Comment As TextBox = DirectCast(FormView.FindControl("txtAddComment"), TextBox)
If Comment.Text = "" Then
Exit Sub
End If
End Sub
The Comment TextBox is not found and the code throws an Object reference error when it tries to access the Text property.
You can find the textbox inside it using ItemDataBound event.
Thanks
You are accessing "txtAddComment" which is there in FormView,then why are you finding FormView in Repeater and then again in textbox in that...you can directly find out it...
Protected Sub FormViewAddComment_ItemInserting(sender As Object, e As FormViewInsertEventArgs)
If (FormView1.CurrentMode == FormViewMode.Insert)
Dim Comment As TextBox = DirectCast(FormViewAddComment.FindControl("txtAddComment"), TextBox)
If Comment.Text = "" Then
Exit Sub
End If
End Sub
EDIT:-
My point is that you are writting the code in ItemInserting Event of FormView,so there you can directly find the FormView.I would suggest to use NamingContainer property in oredr to find the FormView which has trigged the event,by this way you can find the FormView then you can easily find the TextBox in it.
There is example of NamingContainer for Gridview Here

Using FindControl to locate controls in an ASP.Net DetailsView from a VB.Net code-behind file not working

I'm looking to get FindControl to "see" controls in an ASP.Net DetailsView from a VB.Net code-behind file. It doesn't find any of them.
The markup for the page is using a MasterPage.
<%# Page
Title="Attendance"
Language="vb"
AutoEventWireup="false"
MasterPageFile="~/Knowledge Academy.Master"
CodeBehind="Attendance.aspx.vb"
Inherits="Knowledge_Academy.Attendance" %>
<asp:Content
ID="ContentBody"
ContentPlaceHolderID="BodyPlaceholder"
runat="server">
Currently the attributes of a our DetailsView looks like this:
<asp:DetailsView
ID="DetailsView"
runat="server"
AutoGenerateRows="False"
Height="50px"
Width="207px"
DataSourceID="SqlDataSourceDetails"
DataKeyNames="ID"
OnItemCommand="DetailsViewDetails_ItemCommand">
<Fields>
Can you tell me what additional attributes to include so coding like this can "see" the fields in the DetailsView?
Protected Sub DetailsViewDetails_ItemCommand(sender As Object, e As System.Web.UI.WebControls.DetailsViewCommandEventArgs)
Select Case e.CommandName
Case "Add"
Case "Edit"
ButtonAddNewAttendance.Enabled = False
Case "Delete"
Case "Update"
ButtonAddNewAttendance.Enabled = True
Case "Insert"
Case "New"
Dim txtBox As TextBox
txtBox = DetailsView.FindControl("TextBoxDateAttendanceTakenInsert")
txtBox.Text = DateTime.Now
Dim drpValue As DropDownList
drpValue = DetailsView.FindControl("DropDownListClassInsert")
drpValue.SelectedValue = 1
End Select
End Sub
Currently FindControl can't find any of the fields in the DetailsView and gives a Null reference error.
UPDATE *
ItemCommand is not the correct place to put the coding.
I found out that to get this to work, OnDataBinding needs to be added as shown here plus making sure there is a handler in the code-behind file as shown below.
InsertItemTemplate markup:
<InsertItemTemplate>
<asp:DropDownList
ID="DropDownListClassInsert"
Runat="server"
DataSourceID="SqlDataSourceClasses"
DataTextField = "ClassName"
DataValueField="ID"
SelectedValue='<%# Bind("ClassID") %>'
AppendDataBoundItems="True"
ForeColor="Blue"
OnDataBinding="DropDownListClassInsert_DataBinding">
</asp:DropDownList>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorInsertClass" runat="server" ControlToValidate="DropDownListClassInsert"
ErrorMessage="Please select a Class here." Font-Bold="True" Font-Italic="True" ForeColor="Red"
SetFocusOnError="True" Display="Dynamic">
</asp:RequiredFieldValidator>
</InsertItemTemplate>
Handler in the code-behind file:
Protected Sub DropDownListClassInsert_DataBinding(sender As Object, e As EventArgs)
Dim drpValue As DropDownList
drpValue = DetailsView.FindControl("DropDownListClassInsert")
drpValue.SelectedValue = intCurrentClassID
End Sub
Note: intCurrentClassID is declared as:
Public Shared intCurrentClassID As Integer = Nothing
after:
Public Class
I hope this helps others who had the same issues.
I believe that you want to use the Fields property instead of FindControl. Once you have the DataControlField, you can cast it to the appropriate control type (i.e. CheckBoxField).

ASP.NET - GridView - How to programmatically add and read new controls to the cell?

Here is the setup:
I programmatically populate my gridview using LINQ to SQL query. Then I enter the edit mode and want to replace some standard TextBox controls with DropDownLists like this:
'excerpt from GridView1_RowEditing
Dim ddlist1 As New DropDownList
Dim res1 = From items1 In mydb.Items
Select items1.Col10
ddlist1.DataSource = res1
ddlist1.DataBind()
GridView1.Rows.Item(0).Cells(1).Controls.Add(ddlist1)
At this moment I have my gridview showing standard textbox control and new DDList control (in the Column 1).
The problem is -- I cant read the value from DDList in the RowUpdating method. It seems like DDList control is not in the GridView1.Rows.Item(0).Cells(1).Controls collection.
RowUpdating method sees only standard TextBox control and can read it's value.
Any suggestions are welcome. I just don't understand something here :(
Use TemplateField, and then you can locate your dropdown using FindControl
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server">
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
...
Protected Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles GridView1.RowUpdating
Dim ddl = CType(GridView1.Rows(e.RowIndex).Cells(1).FindControl("DropDownList1"), DropDownList)
End Sub

Resources