PreviousPage Findcontrol Issue - asp.net

I need to get the text of the following linkbutton that is set to postback to another page:
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" Text='<%# Bind("computername") %>' PostBackUrl="~/assetdetails.aspx" CommandName="Select">LinkButton</asp:LinkButton>
</ItemTemplate>
I have tried many things in the receiving pages load event but this is what i ended up with:
Dim GV As GridView = TryCast(PreviousPage.Master.FindControl("content").FindControl("GridView2"), GridView)
Dim LB As LinkButton = TryCast(GV.SelectedRow.Cells(0).FindControl("LinkButton1"), LinkButton)
lblAsset.Text = LB.Text
Obviously it doesnt (returns blank, not null) work or i would not be making this post. :)
Please help!

You are doing it wrong way.
Here GridView is inside a Content Page ( which uses a master page), so access the GridView present originally in content page as:
If (Not (Me.Page.PreviousPage) Is Nothing) Then
Dim ContentPlaceHolder1 As Control =
Me.Page.PreviousPage.Master.FindControl("ContentPlaceHolder1")
Dim GV As GridView =
CType(ContentPlaceHolder1.FindControl("GridView1"), GridView)
Dim LB As LinkButton =
TryCast(GV.SelectedRow.Cells(0).FindControl("LinkButton1"), LinkButton)
lblAsset.Text = LB.Text
End If
GridView and other contents are present inside ContentPlaceHolder controls actually.

Related

repeater.findcontrol not working on content page

I have a non content (no master) page with a repeater that performs as I want it to, but when I move the same code to a content page (with master), the findControl in a loop of RepeaterItems no longer works.
aspx:
<ItemTemplate>
<div class="row" id="qrow" runat="server" data-id='<%#Eval("callQuestionID") %>' data-type='<%#Eval("callQuestionResponseType") %>' data-parent='<%#Eval("callQuestionParent") %>'>
<div class="col-md-4">
<asp:Label ID="questonTextLabel" runat="server" Text='<%# Eval("callQuestionText") %>'></asp:Label>
</div>
<div class="col-md-4">
<asp:Panel ID="Panel1" runat="server"></asp:Panel>
</div>
</div>
</ItemTemplate>
ItemDataBound exerp
Dim newRBY As New RadioButton
newRBY.InputAttributes.Add("data-id", CType(e.Item.DataItem, DataRowView)("callQuestionID"))
newRBY.InputAttributes.Add("data-idy", CType(e.Item.DataItem, DataRowView)("callQuestionID"))
newRBY.ID = "rby"
newRBY.Text = "Yes"
newRBY.GroupName = "qid" & CType(e.Item.DataItem, DataRowView)("callQuestionID")
CType(e.Item.FindControl("Panel1"), Panel).Controls.Add(newRBY)
Dim newRBN As New RadioButton
newRBN.InputAttributes.Add("data-id", CType(e.Item.DataItem, DataRowView)("callQuestionID"))
newRBN.InputAttributes.Add("data-idn", CType(e.Item.DataItem, DataRowView)("callQuestionID"))
newRBN.ID = "rbn"
newRBN.Text = "No"
newRBN.GroupName = "qid" & CType(e.Item.DataItem, DataRowView)("callQuestionID")
CType(e.Item.FindControl("Panel1"), Panel).Controls.Add(newRBN)
Post user interaction processing:
For Each questionRow As RepeaterItem In questionRepeater.Items
...
Dim rby As RadioButton = CType(questionRow.FindControl("rby"), RadioButton) ****** Fails Here *****
If rby.Checked Then
dataAccess.callQuestionAnswerTable_Insert(callIDInteger, CInt(rby.InputAttributes("data-id")), "true")
ElseIf CType(questionRow.FindControl("rbn"), RadioButton).Checked Then
dataAccess.callQuestionAnswerTable_Insert(callIDInteger, CInt(rby.InputAttributes("data-id")), "false")
End If
It fails in the post user interaction processing when trying to find 'rby'. The only difference in generated HTML is that in the content page the controls ids get a MainContent_ prefix.
What can I do to resolve this?
If the code is located on the child page, while the Repeater is located on the Master Page itself, you need to specify the Master page with FindControl and locate the Repeater there.
Dim rpt As Repeater = CType(Master.FindControl("Repeater1"),Repeater)
And then
For Each questionRow As RepeaterItem In rpt.Items
(translated from C# to VB with a code translator, so it may be a little off, in C# it is Repeater rpt = Master.FindControl("Repeater1") as Repeater;)
I found my problem. It was actually that I had the binding of the repeater in a
If Not IsPostBack Then
block and I should not have apparently.

Iterating through EditItemTemplate textboxes in asp:Gridview

I have a gridview displaying data within a template field which requires more information about the record to be displayed by clicking on a linkbutton. Right now, I have the "details" linkbutton display the information by calling the edit command on the gridview so that it switches to the EditItemTemplate. Within the EditItemTemplate I have a linkbutton for cancel and then an edit button that, when clicked, displays the update button with the update command, but I need it to iterate through that row and set all the textboxes within the EditItemTemplate to ReadOnly=false so as to allow them to be edited before the update command is selected. Here is a summary of the code:
<ItemTemplate>
*basic information displayed*
<asp:LinkButton runat="server" CommandName="Edit" Text="Details"></asp:LinkButton>
</ItemTemplate>
<EditItemTemplate>
*A bunch of readonly textboxes that display the extra information*
<asp:LinkButton runat="server" CommandName="Update" Text="Update" Visible="false"></asp:LinkButton>
<asp:LinkButton runat="server" Text="Edit" OnClick="editButton_Click"></asp:LinkButton>
</EditItemTemplate>
And the code for the event which makes the buttons appear the way I want, but I'm not sure how to iterate through the EditItemTemplate, or even if this is what I should do:
Protected Sub editButton_Click(sender As Object, e As EventArgs)
sender.FindControl("updateButton").Visible = True
sender.FindControl("editbutton").Visible = False
For Each t In ?EditItemTemplate?
Dim textbox = TryCast(t, System.Web.UI.WebControls.TextBox)
If textbox IsNot Nothing Then
textbox.ReadOnly = False
End If
Next
End Sub
So my question is either how to get this to work, or how I should set up the GridViewCommands otherwise
You should use a PlaceHolder in your EditItemTemplate. Place all of your Controls/LinkButtons inside this placeholder.
<EditItemTemplate>
<asp:PlaceHolder ID="TestPlaceHolder" runat="server">
// Sample Link Buttons
<asp:LinkButton runat="server" CommandName="Update" Text="Update"
Visible="false"></asp:LinkButton>
<asp:LinkButton runat="server" Text="Edit" OnClick="editButton_Click"></asp:LinkButton>
// Sample Text Box
<asp:TextBox runat="server" ID="FirstName" ...>...</TextBox>
</asp:PlaceHolder>
</EditItemTemplate>
Handle the RowEditing event of GridView. Inside the edit event handler, first find the Placeholder, then use the PlaceHolder's Controls property to iterate over the Controls...
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
// Get the Placeholder for the row being edited.
PlaceHolder testPlacehldr =
GridView.Rows[e.NewEditIndex].FindControl("TestPlaceholder") as PlaceHolder;
// Iterate over the controls
if(testPlacehldr.Controls.Count > 0)
{
foreach (Control ctrl in testPlacehldr.Controls)
{
if (ctrl is LinkButton)
{
LinkButton lnkBtn = ctrl as LinkButton
if(lnkBtn.Text== "Update")
{
lnkBtn.Visible = false;
}
// More IF conditions follow....
}
if (ctrl is TextBox)
{
TextBox txtBox = ctrl as TextBox;
if(txtBox.ID == "FirstName")// use any property of TexBox you prefer
{
txtBox.ReadOnly= true;
}
// More IF conditions follow....
}
}
}
//At the End, set the EditIndex and Bind the data
GridView1.EditIndex = e.NewEditIndex;
BindGridViewData();
}
I hope you can workout the logic yourself now for hiding/showing the controls.
So I figured out how to do it (needed it in vb) by using the placeholder within the EditItemTemplate, here's the code behind it:
Protected Sub editButton_Click(sender As Object, e As EventArgs)
sender.FindControl("editbutton").Visible = False
sender.FindControl("updateButton").Visible = True
Dim testPlacehldr As PlaceHolder = sender.FindControl("TestPlaceholder")
If testPlacehldr.Controls.Count > 0 Then
Dim btn As LinkButton = sender.FindControl("editButton")
If btn.Visible = False Then
For Each ctrl As Control In testPlacehldr.Controls
If ctrl.GetType Is GetType(TextBox) Then
Dim box As TextBox = TryCast(ctrl, TextBox)
box.ReadOnly = False
End If
Next
End If
End If
End Sub
This works fine for what I need it to do. Credit to the user R.C. for the idea about placeholders

Passing a values from Datatable to UserControl Property

I am new to programming. I'm creating a program which adds a UserControl to a Gridview template dynamically and I want to pass a value from datatable to a property of a UserControl. The TemplateField in Gridview is already preloaded with 1 user control and if I clicked on a button, this will add a new UserControl with a numbering.
Here is the code from the page on FormLoad event.
Dim dtSESRatings As New DataTable
dtSESRatings.Columns.Add("IncrementNumber")
dtSESRatings.Rows.Add("1")
ViewState("dtSESRatings") = dtSESRatings
gvSesRating.DataSource = dtSESRatings
gvSesRating.DataBind()
And I want to add the row to the Numbering label in the user control which is the IncrementNumber Property set on SESRatings.ascx.
This is the asp code:
<asp:GridView ID="gvSesRating" runat="server" Width="100%" ShowHeader="false" GridLines="None"
AutoGenerateColumns="False">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<ses:SESRatings runat="server" ID="ses1" IncrementNumber="1" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
After FormLoad, upon clicking on a button "ADD NEW RATING", it is supposed to create a new user control in the gridview and the code is here:
Protected Sub btnAddRating_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnAddRating.Click
Dim dt As DataTable = ViewState("dtSESRatings")
Dim dtCnt As Integer = dt.Rows.Count
dtCnt += 1
dt.Rows.Add(dtCnt)
ViewState("dtSESRatings") = dt
gvSesRating.DataSource = dt
gvSesRating.DataBind()
dt = Nothing
End Sub
I want that the user control that will be added in the GridView will get the dtCnt and pass it to the IncrementNumber Property of the User Control. How can I do that? Please help. Thanks.
you must use Eval tags in your gridview control:
<ses:SESRatings runat="server" ID="ses1" IncrementNumber='<%# Eval("IncrementNumber") %>' />

ASP.NET - Accessing a Repeater nested in a GridView column?

I have a blank Repeater nested inside a column in a GridView and want to use a button in the GridView to populate the Repeater on demand via code behind. I am having difficulties referencing the repeater inside my button's onCommand sub.
Here is the relevant markup:
<asp:GridView ID="Submission" runat="server" AllowPaging="true" AllowSorting="true" />
<Columns>
..........
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:ImageButton ID="AdminEditSubmission" runat="server" ImageUrl="edit_15.png"
alt="" OnCommand="loadDetails" CommandArgument="X" />
</ItemTemplate>
</asp:TemplateField>
..........
<asp:TemplateField>
<ItemTemplate>
<asp:Repeater ID="RptSubmissionDetail" runat="server">
</asp:Repeater>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
For the sake of this small example, I will simply try to update the repeater's header with "Hello world". However, when it gets to the last line, I get the dreaded "Object reference not set to an instance of an object" error.
Sub loadDetails(sender As Object, e As CommandEventArgs)
Dim rpt As Repeater = CType(Page.FindControl("RptsSubmissionDetail"), Repeater)
Dim tmpHdr As TemplateBuilder = New TemplateBuilder
tmpHdr.AppendLiteralString("Hello World")
rpt.HeaderTemplate = tmpHdr
End Sub
Can anyone tell me how to reference this repeater from my ImageButton click sub? I have tried several, with Page.FindControl("RptsSubmissionDetail") only being my latest attempt.
In GridView's RowCommand you need to use FindControl on the GridViewRow:
Sub Submission_RowCommand(ByVal sender As Object, ByVal e As GridViewCommandEventArgs)
If e.CommandName = "loadDetails" Then
' Convert the row index stored in the CommandArgument
' property to an Integer.
Dim index = Convert.ToInt32(e.CommandArgument)
' Retrieve the row that contains the button clicked
' by the user from the Rows collection.
Dim row = Submission.Rows(index)
Dim repeater = DirectCast(row.FindControl("RptSubmissionDetail"), Repeater)
End If
End Sub
From the ImageButton's click event it's nearly the same. Cast the sender argument to the ImageButton and it's NamingContainer property to the GridViewRow. Then use FindControl as shown above:
Sub ImageButton_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim img = DirectCast(sender, ImageButton)
Dim row = DirectCast(img.NamingContainer, GridViewRow)
Dim repeater = DirectCast(row.FindControl("RptSubmissionDetail"), Repeater)
End Sub
In your ImageButton Click event write the following code
For Each row As GridViewRow In Submission.Rows
Dim r As Repeater = DirectCast(row.FindControl("RptsSubmissionDetail"), Repeater)
If r IsNot Nothing Then
' do your work
End If
Next
or if you want to find repearter in a particular row you can find it as
Dim r As Repeater = DirectCast(Submission.Rows[0].FindControl("RptsSubmissionDetail"), Repeater) ' Give the right index
If r IsNot Nothing Then
' do your work
End If

Loading a value on the insert command of a detailsview

In a detailsview, how can I prepopulate one of the textboxes on the insertcommand (When the user clicks insert and the view is insert).
I think this would work for codebehind:
Dim txtBox As TextBox = FormView1.FindControl("txtbox")
txtbox.Text = "Whatever I want"
Is this right? What do I need in the aspx (not as sure)? Also, I'm assuming the server-side code will go in the itemcommand or insertcreating event.
I have typed this in VB.NET but I am using C# (I can do both so on a language agnostic forum I might type the problem in another language). I am also using a SqlDataSource, with my parameters and insert/delete/edit commands all created.
I am trying to generate a random GUID (using the GUID object), which will be prepopulated in the textbox.
Also, is the postbackurl property of a button not another way of preserving form state?
Thanks
I would update the field in the DetailsView to a TemplateField:
<asp:TemplateField>
<InsertItemTemplate>
<asp:TextBox ID="txtField" runat="server" Text='<%# Bind("GUID") %>'/>
</InsertItemTemplate>
<ItemTemplate>
<asp:Label ID="lblField" runat="server" Text='<%# Bind("GUID") %>'/>
</ItemTemplate>
</asp:TemplateField>
Then you have two options:
generate your GUID and insert into
your datasource. This may have to be done with SQL since you mentioned using SqlDataSource
remove the binding and access the controls from code in the
DataBound event of your DetailsView
Private Sub dv_DataBound(ByVal sender As Object, ByVal e As EventArgs) Handles dv.DataBound
dim txt as Textbox = dv.FindControl("txtField")
txt.Text = GenerateGUID()
End Sub
I'm guessing you need to use one of detailsview events.
Hook up to ItemCommand, ModeChanging or ModeChanged events and fill your value there.
I am doing something like this as well. I am hiding the DetailsView and showing it when the user clicks a button.
dvDetails.ChangeMode(DetailsViewMode.Insert)
pnlDetailMenu.Visible = True
Dim ColumnTextBox As TextBox
ColumnTextBox = dvDetails.Rows(0).Cells(1).Controls(0)
If Not ColumnTextBox Is Nothing Then
ColumnTextBox.Text = "Initial Value"
End If

Resources