VB.NET AddHandler throwing Object reference not set - asp.net

I have an ASP.NET page with code-behind in VB.NET. On the ASPX page I have a Repeater with an asp:ImageButton inside the repeater and I want to catch the clicks on the button. As far as I read I have to use FindControl and then handle the copy of the original control:
Codebehind:
Dim imagebutton1 As ImageButton = repeater.FindControl("btnImage1")
AddHandler imagebutton1.Command, AddressOf ReportTransfer
...
...
Protected Sub ReportTransfer(ByVal sender As ImageButton, ByVal args As CommandEventArgs)
...
End Sub
ASPX page:
<td>
<asp:ImageButton runat="server" ID="btnImage1" ImageUrl="~/images/icons/icon_small.png"
CommandArgument="3" />
</td>
</tr>
</ItemTemplate>
It throws "Object reference not set to an instance of an object" on the AddHandler line and I have no idea why it is doing it (I'm a bit new with VB.NET)
Thank you in advance

You should be handling ItemCommand event of the Repeater. In this event CommandSource is the image button. Either the CommandArgument or CommandName needs to indicate what command you actually want to perform. Setting the CommandArgument to 3, means each image button will have the same value.
The repeater.FindControl("btnImage1") is not going to work because each button's id is going to change.
Adding the handler is not correct.
Repeater.ItemCommand Event; Occurs when any button is clicked in the Repeater control; http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater.itemcommand.aspx

You're getting "Object reference not set to an instance of an object" because imagebutton1 is null. Make sure you're actually finding a control before adding a handler.
AMissico is right, you want to actually subscribe to the Repeater's ItemCommand event, and use the CommandArgument to identify what row the user clicked on.

Related

odd behavior when when changing linkbutton text

In my project, I have a datarepeater, in an updatepanel, with a linkbutton. When the user clicks the linkbutton, a partial post back occurs and changes the text property of the linkbutton. The problem is: when the user clicks the same button again, even though i can physically see the new text value on the web page, when the debugger hits the event, the sender object says the text value is the old value, not the last updated. Anyone know why? Here is the code:
<asp:LinkButton runat="server" ID="lbEdit" Text="Edit" EnableViewState="true" OnClick="edit_click" CommandArgument='<%# Eval("user.networkId") %>'></asp:LinkButton>
codebehind:
Protected Sub edit_click(ByVal sender As Object, ByVal e As EventArgs)
Dim btn As LinkButton = CType(sender, LinkButton)
Dim userId As String = btn.CommandArgument
If (btn.Text = "Edit") Then
btn.Text = "Save"
else
btn.Text = "Edit"
end if
end sub
Most likely you are rebinding your data on postback, so it is resetting your value. Then the button click event is firing, so yes you are setting Text correctly. But when you postback again, the text is getting reset.
Wrap your DataBind event in a If Not IsPostBack:
If Not IsPostBack
'Bind your datasource
End If

ImageButton not firing

I have the following button:
<asp:ImageButton ID="imgbtnEditInfo" runat="server" ImageUrl="~/images/EditInformation.png" AlternateText="EditInformation" CommandName="EditDetails" CommandArgument="<%# Container.DataItemIndex %>" OnClick="lnkEdit_Click" Enabled="true" />
I have the following method but looks like it is not hitting the method:
Protected Sub lnkEdit_Click(ByVal sender As Object, ByVal e As System.EventArgs)
End Sub
Wondering if I am missing something. I put a breakpoint on the Protected Sub lnkEdit_Click but on click of the imagebutton I do not go there.
You're working with Data Controls (GridView or DataList etc). To respond to the button/linkbutton/imagebutton events, you must have to handle the parent - data control's events.
Without seeing more of your page it is hard to say. A couple things to check:
Is the ImageButton inside a <form runat="server">?
Have you compared your page to the VB sample at ImageButton Class to see if anything might have been missed?

how to send the value of a textbox from one page to another using querystring

I have a page1 and link on that page which opens up the Page2. There is a textbox on Page1 whose value needs to be passed onto the Page 2 when the user clicks on the link for Page2.
Firstly, I thought of using onTextbox changed event, but cant use that as the values in the textbox are autogenerated.
Once the Page1 is loaded the value in the textbox is 1 which needs to be passed onto Page2 when Page2 is clicked.
i want to do this using querystring.
inputs please.
You could easily do that with a LinkButton. Handle the click event on the LinkButton for Page2, and then construct your Response.Redirect with the appropriate QueryString key/value pairs:
HTML:
<asp:TextBox ID="TextBox1" runat="server" />
<asp:LinkButton ID="LinkButton1" runat="server" Text="Page2" />
CODE-BEHIND:
Private Sub LinkButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LinkButton1.Click
Response.Redirect(String.Format("Page2.aspx?tb={0}", Server.HtmlEncode(TextBox1.Text)))
End Sub
You could use a LinkButton and handle its click event in codebind. There you can Response.Redirect to Page2 and append the TextBox' Text to the QueryString.
Dim newLink as String = _
String.Format("Page2.aspx?TextBox1Text={0}", Server.HtmlEncode(TextBox1.Text))
Response.Redirect(newLink)
Why not use POST and Server.Transfer?
Using Server.Transfer then you can get access to all form properties from the previous page.
http://msdn.microsoft.com/en-us/library/ms525800%28v=vs.90%29.aspx

Repeater won't let me access controls like buttons, dropdown, etc

I'm using a repeater ListOfArticles and have controls inside it like ddlSizes and btnSelectArticle. Normally you can just double click the control and in the aspx.vb page you can specify an action. I have heard something about Findcontrol, but can't figure out or find much information that I understand. I don't want to sound like an ass, but I would really prefer help for the aspx.vb page and not in C# or Javascript.
An example of what I'm trying to do is, once you've clicked btnSelectArticle the label lblSelection receives the following values Amount: txtAmount - Size: ddlSizes.SelectedValue.
<asp:Repeater ID="rptListOfArticles" runat="server" DataSourceID="objdsArticleList">
<asp:DropDownList ID="ddlSizes" runat="server" AutoPostBack="True" DataSourceID="objdsSizes" DataTextField="SizeName" DataValueField="SizeID" OnSelectedIndexChanged="ddlSizes_SelectedIndexChanged" />
<asp:Button ID="btnSelect" runat="server" Text="Select" OnClick="btnSelect_OnClick" />
<asp:Label ID="lblSelection" runat="server" Text=""></asp:Label>
In the aspx.vb page I can only select this and my controls like ddlSizes and btnSelect aren't recognized.
Protected Sub rptListOfArticles_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.RepeaterCommandEventArgs) Handles rptListOfArticles.ItemCommand
End Sub
Any help towards a solution would be great!
What you need to do is use the FindControl method to find the specific control in the selected repeater Item.
so an example would be (within the ItemCommand method)
Dim lblSelection as Label = CType(e.Item.FindControl("lblSelection"), Label)
lblSelection.Text = "Your Text"
Edit **
To Answer your questions in the comments:
Yes to access the SelectedValue of the ddlSize DropDown you will need to create this:
Dim ddlSize As DropDownList = Ctype(e.Item.FindControl("ddlSize"), DropDownList)
The Repeater will know when to call this method when any Buttons are Clicked within the Repeater. Add a CommandName to your buttons so that you can then control what happens in the ItemCommand method.
e.g.
<asp:Button id="btnDoSomething" runat="server" text="Run ItemCommand" CommandName="Command1" />
In the ItemCommand use the code:
If e.CommandName = "Command1" Then
' run your code
End If
You can handle the event of dropdownlist in ItemCommand Event. Event bubbling concept comes here actually the child control bubble the evenet up to its parent i.e repeater control so you can handle it in parent control event eventually
for more details HERE you will have indepth insight of all events of repeater

Why is my CommandArgument Empty?

I have an ASP.Net page, which displays a list of options to the user. When they select from the list, it does a post back and queries a sql server. The results are displayed in a listview below the options in an update panel. Below is a snippet of the ItemTemplate:
<asp:LinkButton Text="Save IT" OnCommand="SaveIt" CommandArgument="<%# Container.DataItemIndex %>" runat="server" />
The DataItemIndex does not appear, so my commandargument is empty. However, the object sender is the button, which shows the item.
Why is the index item not appearing in the CommandArgument?
Could it be the post back? If so, why would it be the post back? Is there a way around it?
Edit:
Sorry, from my attempts to solve it before, I posted bad code, but it still isn't appearing.
Resolution:
I found another work around in that the sender of the OnCommand is the link button, which has the CommandArgument. I will chalk this issue up to be an issue with multiple postbacks and javascript.
You can't use the <%= %> syntax inside properties on a tag with a runat="server" attribute. I'm surprised the code will even run. :)
UPDATE:
You probably want to use the ItemDataBound event on the repeater, find the linkbutton and set the CommandArgument property.
Not very elegant, but here's a VB.NET sample.
Private Sub Repeater1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles Repeater1.ItemDataBound
Select Case e.Item.ItemType
Case ListItemType.Item, ListItemType.AlternatingItem
Dim b As LinkButton = e.Item.FindControl("btn")
b.CommandArgument = e.Item.ItemIndex
b.DataBind()
End Select
End Sub
You're not setting it
You possibly want
<%# Container.DataItemIndex %>
or
<%= Container.DataItemIndex %>
:)
Try
<asp:LinkButton Text="Save IT" OnCommand="SaveIt" CommandArgument="<%# Container.DataItemIndex %>" runat="server" />
You were missing the "#" sign.
This site really helped me with this problem: http://forums.asp.net/t/1671316.aspx
The issue I ran into was that I was being passed null arguments in the commandargument when I clicked on the button a second time. As the post above explains, this is because commandargument is only set in the databind event. So, to fix this, include a databind event in the page_load sub
Ex. (VB)
Private Sub BindSelectButtons()
'Purpose: bind the data to the select buttons for commandargument to be used
Dim i As Integer
For i = 0 To gridview1.Rows.Count - 1
gridview1.Rows(i).Cells(8).FindControl("btnID").DataBind()
Next
End Sub
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
'Rebind select buttons so that the commandargument refreshes
BindSelectButtons()
End Sub
Make sure View State is enabled
e.Row.EnableViewState = true;

Resources