ASP.NET - Dynamically Accessing Controls - c#

I have the following control on my ASPX page:
<asp:TextBox ID="txtISBN13" runat="server" ClientIDMode="Static" />
I need to access this element without referring to it explicitly. Because this control does not yet exist during the Page_Load event, I have to access it later in the Page Life Cycle.
I've tried overriding the OnUnload event, because this is the final event, but I still can't access my control by either:
Control c = new Control();
c.FindControl("txtISBN13");
Or:
Control c = Page.FindControl("txtISBN13");
Am I overriding the incorrect event? Is ClientIDMode screwing with me? Even if I try similar code on a button click event, I get no luck. Do I need some kind of recursive FindControl? Should I be using Page.FindControl or Control.FindControl?
For this situation, I am unable to do:
this.txtISBN13.Text = "Foo";
Instead, I'll have a DataColumn (previousValue), and I need to find that control and set it's value. I'm trying:
string pendingID = String.Format("txt{0}", previousValue.ColumnName);
TextBox txt = new TextBox();
txt.ID = pendingID;
txt.Text = "Foo";

Assuming that the inputs are in some sort of container (PlaceHolder, Panel, etc.) you should be able to do this:
Markup:
<asp:PlaceHolder ID="PlaceHolder1" runat="server">
<asp:TextBox ID="txtISBN1" runat="server" />
<asp:TextBox ID="txtISBN2" runat="server" />
....
<asp:TextBox ID="txtISBN13" runat="server" />
</asp:PlaceHolder>
Code-behind:
TextBox txt = PlaceHolder1.Controls.OfType<TextBox>().FirstOrDefault(x => x.ID.ToUpper().Contains("ISBN13"));
if (txt != null)
{
txt.Text = row.Field<string>("ISBN13");
}

What container is your control in? You'll need to call containingControl.FindControl("txtISBN13"), or search recursively in the Page.Controls - C#, FindControl.

Related

Access textbox within asp.net repeater

I have a nested asp repeater which is displaying all my items correctly. I have another div within the ItemTemplate of each repeater which submits content to my code behind.
<asp:Repeater runat="server" id="repeaterNote" OnItemDataBound="repeaterNote_ItemDataBound">
<ItemTemplate>
<div id="note" class="staff"><p><%# Eval("Content") %></p><ul>
<li><%# Eval("AddedDate") %></li><li>20:29</li>
<li><%# Eval("AddedByName") %></li><li>
Add comment</li></ul>
<div id="addComment<%# Eval("NoteID") %>" class="staff" style="display:none">
<asp:TextBox ID="notecommenttext" runat="server" rows="4"> </asp:TextBox>
<asp:Button ID="Button" runat="server" Text="Add" CommandArgument='<%# Eval("NoteID") %>' OnCommand="Add_Comment" />
</div>
</div>
When I submit the button I want to retrieve the content within the textbook "notecommenttext". There doesn't seem to be an easy way to do this. I have tried to set the ID of the textbook to the unique "NoteID" but it appears that cannot be done.
string uniqueNoteID = e.CommandArgument.ToString();
int parent = int.Parse(uniqueNoteID);
TextBox txtName = new TextBox();
foreach(RepeaterItem noteItem in repeaterNote.Items)
{
if (noteItem.ItemType == ListItemType.Item || noteItem.ItemType == ListItemType.AlternatingItem)
{
Notes rin = (Notes)noteItem.DataItem;
if (rin.RelativeNoteId == parent)
{
txtName = (TextBox)noteItem.FindControl("notecommenttext");
}
}
}
The snippet above is from the button callback "Add_Comment", repeaterNote is my top level Repeater id. It seems to have the correct number of RepeaterItems but the DataItem property is always null. I have added an inner foreach loop to iterate over my nested repeater. Again, this correctly identifies only one of the top level repeaters has a nested repeater element, but the DataItem is still null.
Any suggestions on how I can access the content from within the textbook of each repeater?
I think instead of setting OnCommand in your button, you should set OnItemCommand in your repeater to your event handler and just set the CommandName property in your button to an easily identifiable string. Then in the repeater's OnItemCommand event handler, you do a Select Case on e.CommandName, and if it's that button's CommandName that you set, you can use e.Item.FindControl("notecommenttext") to get your textbox control. Then get its content. When a control is in a repeater its ID gets a bunch of stuff appended to it so it is hard to find outside of a repeater event like ItemCommand.
I think your problem is that you are doing the Binding mecanism in your Page_Load() method without testing if (!IsPostback) That's why you dont find the result you want. Don't forget to set EnableViewState="False"
So you should move your Binding mecanism in Page_LoadComplete() method if you are in aspx page or add in your page load
if(!IsPostback)
{
//your binding mecanism
}

Add asp:textbox dynamically in ASP.NET

I have an aspx page made with ASP.NET Web Forms. What i need to create is two asp:textbox fields. I want to be able to dynamically add two new fields below that with the press of a button.
So basically i want to be able to add an infinite amount of "new" textfields. But i'm not sure how to do this in ASP.NET.
Is there perhaps a way to create an arrat of those textfields? So that when a form is posted i can easily iterate over them?
How can i do this?
In your aspx file:
<asp:TextBox runat="server" ID="textbox1"/>
<asp:TextBox runat="server" ID="textbox2"/>
<asp:Button runat="server" ID="btnAdd" OnClick="btnAdd_Click" />
<asp:PlaceHolder runat="server" ID="ph" />
In your aspx.cs file:
protected void btnAdd_Click(object sender, EventArgs e)
{
TextBox tb1 = new TextBox();
TextBox tb2 = new TextBox();
ph.Controls.Add(tb1);
ph.Controls.Add(tb2);
}
You can add this fields and make them hidden(invisible).
And you can show fields on button click (with javascript).
Dynamically adding serverside controls is problem.

The Value Of A Check Box Is Empty Using An Enumeration Inside A Repeater (ASP.NET Web Forms)

I have a repeater and I set the value of an html check box control with the
value of an enumeration instead of hard-coding a magic number. When I try to
access the html check box control in the repeater's ItemCreated event handler,
the value is an empty string. Why is this and how can I fix it?
C# Code
protected void Repeater1_ItemCreated(object sender, RepeaterItemEventArgs e)
{
var myObject = e.Item.DataItem as MyObject;
if (myObject != null)
{
var checkBox = e.Item.FindControl("checkbox1") as HtmlInputCheckBox
// The value is empty!
var value = checkBox.Value;
}
}
Not Working
<asp:Repeater ID="Repeater1" OnItemCreated="Repeater1_ItemCreated" runat="server">
<ItemTemplate>
<input type="checkbox" id="checkbox1" value='<%# SomeEnum.Value %>' />
</ItemTemplate>
</asp:Repeater>
Working
<asp:Repeater ID="Repeater1" OnItemCreated="Repeater1_ItemCreated" runat="server">
<ItemTemplate>
<input type="checkbox" id="checkbox1" value="1" />
</ItemTemplate>
</asp:Repeater>
ItemCreated is triggered before ItemDataBound and also on every postback to recreate he controls even when the Repater is not databound again. So i would not use ItemCreated if you need to access the DataSource of any databound WebControl like Repeater.
Apart from that, make the checkbox runat=server(or use a ASP.NET CheckBox) if you want to find it on the server.

Calling function in usercontrol inline code doesn't always work

I have constructed an ASP.NET user control "Box.ascx" wtih the following code.
<div id="divContent" runat="server" visible='<%# AllowedToView(this.Privacy) %>'>
Content
</div>
In the codebehind, "Box.ascx.cs" has the following code.
public string Privacy = string.Empty;
public bool AllowedToView(string privacy)
{
return true;
}
When I use this control in a repeater, AllowedToView() function is hit. If I use this control without a repeater, AllowedToView() function isn't called. I want to know why this weird situation happens and how can I make the control call the AllowedToView() function when used without repeater.
Details are below.
I use this control in a repeater in "Default.aspx".
<asp:Repeater ID="rpRecords" runat="server">
<ItemTemplate>
<uc1:Box ID="myBox" runat="server" RecordID = '<%# Eval("RecordID") %>' />
</ItemTemplate>
</asp:Repeater>
The repeater is databound in "Default.aspx.cs" with the following code:
DataTable dt = FillTable();
rpRecords.DataSource = dt;
rpRecords.DataBind();
I use the "Box.ascx" control in "ShowBox.aspx" with the following code.
<body>
<uc1:Box ID="myBox" runat="server" />
</body>
I give values to the user control from the codebehind with the following code.
protected void Page_Load(object sender, EventArgs e)
{
myBox.RecordID = "1";
}
As mentioned in another answer, the # means it will require databinding to be executed.
So to answer your question "How to make it run outside of the repeater" the simple answer is to call myBox.DataBind().
Your question is very similar to asp.net inline code <%# MyboolVal %>. The problem is that <%= is equal to Response.Write and outputs straight HTML, so it won't work when setting the visible property.
I don't think you need the # but instead = in the ASP tag. Pretty sure # is only for databinding events and that's why it works in a repeater because a repeater performs a databound for rendering.
Check this link: http://blogs.msdn.com/b/dancre/archive/2007/02/13/the-difference-between-lt-and-lt-in-asp-net.aspx
Im no expert on webforms but i think that your problem is that you are trying to databind that method and thats not working for you, try putting it in a <%= AllowedToView(this.Privacy) %>

How Do I Get a Dynamic Control's Value after Postback?

I have a listview that adds controls in the ItemDataBound Event. When the postback occurs, I cannot find the new controls. After a bit of research, I found that ASP .NET needs these controls created every time, even after postback. From there I moved the function to bind the ListView outside of the if (!Page.IsPostBack) conditional. Now I get the dynamic controls values but the static controls I have are set to their defaults. Here is a sample of what I am trying to accomplish:
For brevity, I left some obvious things out of this example.
<asp:ListView runat="server" ID="MyList" OnItemDataBound="MyList_ItemDataBound">
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceholder" />
</LayoutTemplate>
<ItemTemplate>
<asp:PlaceHolder runat="server" ID="ProductPlaceHolder">
<asp:TextBox runat="server" ID="StaticField" Text="DefaultText" />
<asp:PlaceHolder ID="DynamicItems" runat="server" />
</asp:PlaceHolder>
</ItemTemplate>
</asp:ListView>
and here is the codebehind:
protected void MyList_ItemDataBound(object sender, System.Web.UI.WebControls.ListViewItemEventArgs e) {
PlaceHolder DynamicItems = (PlaceHolder)e.Item.FindControl("DynamicItems");
DynamicItems.Controls.Add(textbox);
}
So, like I said, if I only databind when Page != PostBack then I cant find my dynamic controls on postback. If I bind every time the page loads then my static fields get set to their default text.
Try moving the data binding of the ListView into the OnInit() event.
Very similar question (instead of populating a ListView the guy is generating a set of buttons). Briefly, you'll find that you have to store the items in the list in your Viestate - than fish it out on Postback and re-populate the list.
Note that this solutions implies dropping data-binding (which you might not wanna do for others reasons).
Hope it helps.

Categories