How do I retrieve the control contents in a dynamic table? - asp.net

I have a page where I would like to collect information about x number of users. I have a control where you enter in the number of users and based off of that number, I create a dynamic table with a row for each user. Each table row has textbox controls that I would like to retrieve the value from on postback. How can this be accomplished?

What particular style of ASP.Net are you targeting? ASP.Net MVC? Webforms?
The quickest and easiest way to do something like this in webforms (which Im way more familiar with) would be to drop a GridView control on the page, and bind a generic collection to it that you set the size of based on the number entered in the control.
Here's a quick 10m piece of code. Created a default WebForms Web project in Visual Studio 2010.
Web Page Source:
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<p>
<table>
<tr>
<td>Rows:</td>
<td><asp:TextBox ID="TextBox1" runat="server" />
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
</td>
</tr>
<tr>
<td colspan=2>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="Button2" runat="server" onclick="Button2_Click" Text="Button" />
</td>
</tr>
</table>
</p>
</asp:Content>
Code behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
List<string> users = new List<string>(Enumerable.Repeat(string.Empty, Int32.Parse(TextBox1.Text)));
GridView1.DataSource = users;
GridView1.DataBind();
}
protected void Button2_Click(object sender, EventArgs e)
{
var list = from GridViewRow row in GridView1.Rows
where row.RowType == DataControlRowType.DataRow
select (row.FindControl("TextBox2") as TextBox).Text;
// now do something with this list of strings
}
}
}

You may find it much easier to create an asp:GridView instead. You can then iterate through the rows on postback and inspect the controls. Lots of example code out there.

Related

can't access a property using <%# %>

i was trying to hide and show a button using following code
where AllowUpdate is a property of page.
now problem is This statement never get Executed.
I have used similar code on other pages but it is unreliable many times it just fails and hides buttons even if they must not be
<asp:Button runat="server" ValidationGroup="param" Text='<%$ Resources:Resources, Save%>' ID="btnsave" CssClass="btn btn-primary btn_round" OnClick="btnsave_Click" Visible="<%# AllowUpdate %>" />
If you're going to use the <%# %> syntax, you must call data bind.
<asp:Panel runat="server" ID="Panel1">
<%# SomeProperty %>
</asp:Panel>
Code behind:
Panel1.DataBind();
Alternatively, use the <%= %> syntax.
<%= SomeProperty %>
or as Cal279 points out in the comments, you can set it in your code behind on some event, such as Page_Load.
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
Butbtnsaveon1.Visible = AllowUpdate;
}
}

wizard and asyncfileupload in next step

In my ASP.NET .NET 3.5 I have custom control that has UpdatePanel inside.
In that update panel I Wizard control with 7 steps.
In second step I want to upload attachments using AsyncFileUpload.
In my scenario user can add multiple files and they will show inside grid, so after upload he can add comments to them.
Everything works file if I have AsyncFileUpload in Step that is visible at beginning, UploadedComplete event is fired correctly, but when I start from different step I can't get that Upload to work.
I was thinking about using iframe, but I would like to avoid it because I need to have 5 upload components in different Steps.
Is it possible to get that AsyncFileUpload to work in Wizard?
My code is standard, nothing magical at moment:
ToolkitScriptManager
UpdatePanel
-ContentTemplate
--Wizard
---WizardSteps
----WizardStep 1
----WizardStep 2
-----AsyncFileUpload
----WizardStep 3
----WizardStep 4
-----AsyncFileUpload 1
-----AsyncFileUpload 2
----WizardStep 5
And my simple event handler
protected void AsyncFileUpload1_UploadedComplete(object sender, AjaxControlToolkit.AsyncFileUploadEventArgs e)
{
var fileUpload = (AjaxControlToolkit.AsyncFileUpload)sender;
if (fileUpload.HasFile)
{
string strPath = path + e.FileName;
AsyncFileUpload1.SaveAs(strPath);
}
}
As I wrote before I get that event if I start from Step 2 (ActiveStepIndex=1).
Here is my ascx code:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="PWS_Test.ascx.cs" Inherits="kontrolki_PWS_Test" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Wizard ID="Wizard1" runat="server" ActiveStepIndex="0">
<WizardSteps>
<asp:WizardStep runat="server" title="Step 1">
<asp:Label ID="Label1" runat="server" Text="Questions"></asp:Label>
<br/>
<asp:CheckBox ID="CheckBox1" runat="server" Text="One"/>
<br/>
<asp:CheckBox ID="CheckBox2" runat="server" Text="Two"/>
</asp:WizardStep>
<asp:WizardStep runat="server" title="Step 2">
<asp:Label ID="Label2" runat="server" Text="Choose Your image"></asp:Label>
<br />
<asp:AsyncFileUpload ID="AsyncFileUpload1" runat="server" FailedValidation="False" OnUploadedComplete="AsyncFileUpload1_UploadedComplete" />
</asp:WizardStep>
</WizardSteps>
</asp:Wizard>
</ContentTemplate>
</asp:UpdatePanel>
And here is cs code:
using System;
public partial class kontrolki_PWS_Test : System.Web.UI.UserControl
{
protected const string path = #"c:\temp\";
protected void Page_Load(object sender, EventArgs e)
{
}
protected void AsyncFileUpload1_UploadedComplete(object sender, AjaxControlToolkit.AsyncFileUploadEventArgs e)
{
var fileUpload = (AjaxControlToolkit.AsyncFileUpload)sender;
if (fileUpload.HasFile)
{
string strPath = path + e.FileName;
AsyncFileUpload1.SaveAs(strPath);
}
}
}
This works when I start from step 2.
As a workaround I've created a hidden div in my control just before wizard:
<div style="display: none">
<asp:AsyncFileUpload ID="AsyncFileUpload2" runat="server" />
</div>
and now my upload is working, but I would like normal solution instead of that workaround.
Add the attribute: enctype="multipart/form-data" to your <form> tag.
<form id="form1" runat="server" enctype="multipart/form-data">
...
...
</form>

Displaying collection in Repeater control

I'm beginner in Asp.Net and Im trying to display "gc" on reapet control.
Here's the code-behind:
public partial class _Default : System.Web.UI.Page
{
List<GlassesCollection> gc= BL.Example.GetCategory() ;
protected void Page_Load(object sender, EventArgs e)
{
rpt1.DataSource = gc;
rpt1.DataBind();
}
protected void rpt1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
}
Im using the following ASP code:
<asp:Repeater ID="rpt1" runat="server" onitemdatabound="rpt1_ItemDataBound">
<ItemTemplate>
<%# Eval("gc") %>
</ItemTemplate>
</asp:Repeater>
But in run time i get this Exception:
Exception Details: System.Web.HttpException: DataBinding: 'ISeeOptic.DataType.GlassesCollection' does not contain a property with the name 'gc'.
Why i get this Excption and idea how to solve this?
Thank you in advance!
Try eval the specific property rather than the object
<asp:Repeater ID="rpt1" runat="server" onitemdatabound="rpt1_ItemDataBound">
<ItemTemplate>
<%# Eval("gcProperty") %>
</ItemTemplate>
</asp:Repeater>
The SO Question gives more details about binding a repeater to a generic list.
You can generally take advantage of DataBinder class which has the most power and flexibility the same as code listing here...
<asp:Repeater ID="rpt1" runat="server" onitemdatabound="rpt1_ItemDataBound">
<ItemTemplate>
<%# DataBinder.Eval("gcProperty") %>
</ItemTemplate>
</asp:Repeater>

Linkbuttons do not work in IE when a div is present around a button

This is more like I would like to know why. The link buttons work in Firefox and Chrome but not in IE-8.
EDIT:
Figures it works in IE-7 but not 8
Now if you remove the
<div>
</div>
then all the links work fine. Anyone know why.
AXPX PAGE
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="testPage.aspx.cs" Inherits="MyCompany.WEB.Pages.Secured.testPage" MasterPageFile="~/Layouts/Branding.Master" Theme="Default" %>
<%# Register Assembly="DBauer.Web.UI.WebControls.DynamicControlsPlaceholder" Namespace="DBauer.Web.UI.WebControls" TagPrefix="DBWC" %>
<%# Register TagPrefix="MyCompany" TagName="Toolbar" Src="~/Controls/ToolbarViewer.ascx" %>
<asp:Content ID="conToolbar" runat="server" ContentPlaceHolderID="cphToolbar">
<MyCompany:Toolbar ID="incToolbar" runat="server" />
</asp:Content>
<asp:Content ID="conHome" runat="server" ContentPlaceHolderID="cphMain">
<asp:ListView ID="lvProducts" runat="server" OnItemDataBound="lvProducts_ItemDataBound">
<EmptyDataTemplate>There are no primary UITs</EmptyDataTemplate>
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
</LayoutTemplate>
<ItemTemplate>
<asp:UpdatePanel ID="pnlMainUpdate" runat="server" UpdateMode="Conditional" >
<ContentTemplate >
<asp:Repeater ID="rptLineItems" runat="server" OnItemDataBound="rptLineItems_ItemDataBound" >
<ItemTemplate>
<asp:Panel runat="server" ID="pnLineItem" CssClass="Block ClearBoth UITOrderGroup Ledger OrderBorder FloatLeft UITOrderHeight">
<asp:LinkButton ID="lnkAddRow" runat="server" CssClass="IconButton Block Add" style="width:20px;" ToolTip="Add Row" CommandName="AddItem" OnCommand="lnkRow_Command" ></asp:LinkButton>
</asp:Panel>
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
</asp:ListView>
<div class="floatRight">
<asp:button ID="btnSubmit" runat="server" CssClass="DefaultButton floatRight" Text="Order" ToolTip="Click here to Order" Visible="true"></asp:button>
</div>
</asp:Content>
CODE BEHIND
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace MyCompany.WEB.Pages.Secured
{
public partial class testPage : MyCompanyPageBase
{
protected void Page_Load(object sender, EventArgs e)
{
lvProducts.DataSource = new List<int>() {1,2,4,5,6};
lvProducts.DataBind();
}
protected void lvProducts_ItemDataBound(object sender, ListViewItemEventArgs e)
{
var dataItem = (ListViewDataItem)e.Item;
var rptLineItems = (Repeater)dataItem.FindControl("rptLineItems");
rptLineItems.DataSource = new List<int> { 1,2,3,4,5 };
rptLineItems.DataBind();
}
protected void lnkRow_Command(object sender, CommandEventArgs commandEventArgs)
{ }
protected void rptLineItems_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
}
}
}
I suspect that your styling is causing the LinkButton not to render correctly. Remove the CssClass property from the Panel and see if that makes a difference.
While debugging this issue, I would temporarily remove the UpdatePanel too. It's easier to debug these kinds of issues without AJAX.
It turns out that You have to set the Text property for the controls in the list view.
<ItemTemplate>
<asp:Panel runat="server" ID="pnLineItem" CssClass="Block ClearBoth UITOrderGroup Ledger OrderBorder FloatLeft UITOrderHeight">
<asp:LinkButton ID="lnkAddRow" runat="server" CssClass="IconButton Block Add" style="width:20px;" ToolTip="Add Row" CommandName="AddItem" OnCommand="lnkRow_Command" Text="" ></asp:LinkButton>
</asp:Panel>
</ItemTemplate>

ASP.NET Change Dropdown Control ID Inside Repeater Item Dynamically

Can someone tell me how I can get this to work. I want to distinguish dropdown controls inside a repeater control. I understand now about the lifecyle and how the buffer is already writen, but what are my alternatives? Here is what happens
Code File
Dim repeatTimes((TotalAdInsured - 1)) As Integer
myRepeater.DataSource = repeatTimes
myRepeater.DataBind()
Aspfile
<asp:Repeater ID="myRepeater" runat="server">
<ItemTemplate>
<asp:DropDownList ID="AdTitle<%# Container.ItemIndex %>" runat="server">
<asp:ListItem Selected="True" Value="" Text=""/>
<asp:ListItem Selected="False" Value="Miss" Text="Miss"/>
<asp:ListItem Selected="False" Value="Ms" Text="Ms"/>
<asp:ListItem Selected="False" Value="Mrs" Text="Mrs"/>
<asp:ListItem Selected="False" Value="Mr" Text="Mr"/>
<asp:ListItem Selected="False" Value="Other" Text="Other"/>
</asp:DropDownList>
</ItemTemplate>
</asp:Repeater>
Returns this error
Parser Error Message: 'AdTitle<%# Container.ItemIndex %>' is not a valid identifier.
I want to distinguish dropdown
controls inside a repeater control.
You don't need to. Here's some sample code that might help you out:
Markup:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label runat="server" ID="lblMsg" Text="Click a button" />
<hr />
<asp:Repeater runat="server" ID="rptAwesome" onitemcommand="rptAwesome_ItemCommand"
>
<ItemTemplate>
<asp:Button runat="server" ID="btnAwesome"
Text='<%# "Button #" + Container.ItemIndex %>'
CommandArgument='<%# Container.DataItem %>'/><br />
</ItemTemplate>
</asp:Repeater>
</div>
</form>
</body>
</html>
Codebehind:
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
var x = new int[] { 1, 2, 3, 4, 5 };
rptAwesome.DataSource = x;
rptAwesome.DataBind();
}
}
protected void rptAwesome_ItemCommand(object source, RepeaterCommandEventArgs e)
{
Button btnAwesome = (Button)e.CommandSource;
lblMsg.Text = string.Format("btnAwesome.ID = {0}, e.CommandArgument = {1}", btnAwesome.ID, e.CommandArgument);
}
}
You cannot create a Unique ID inside a repeater through the markup like that. You can however retrieve the dropdown in the codebehind by using FindControl on the Repeater.
Dim adTitle As DropDownList = MyRepeater.FindControl("AdTitle")
If (Not adTitle Is Nothing) Then
''Do something here
End If
Ok... in a nutshell you can't do what you're trying to do in the manner you are currently doing it.
The ID property of a control can only be set using the ID attribute in the tag and a simple value. Example: <asp:Button runat="server" id="Button1" />
I can see what your trying to do, but I don't really understand Why...
A repeater control will contain 1 item, per item in your datasource, so it's perfectly fine to just call your DropDownList ID="AdTitle" as that will be a different 'AdTitle' from the one in the next row.
To get them back server side, you would just iterate through the Items in your Repeater & FindControl("AdTitle") to get the specific DropDownList for that item.
If it's absolutely necessary to have the IDs incrementing, you'll need to do this programmatically (probably on the ItemDataBound event to create a DropDownList and add it to your ItemTemplate.
Expanding on BC's answer: I recently had the same issue, albeit with a checkbox, I needed to set the ID as I used that when persisting choices. A bit clunky but I did it when on Item Data Bound.
Here's the markup:
<asp:Repeater ID="Repeater1" runat="server" >
<HeaderTemplate>Header<br /><br /></HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="cb" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>' />
...other controls removed for brevity
</ItemTemplate>
<FooterTemplate>
<asp:Button ID="Button1" runat="server" OnClick="Submit" Text="Submit" />
</FooterTemplate>
</asp:Repeater>
I set up and bound a collection of this class
public class mst
{
public int Id { get; set; }
public string Name { get; set; }
public string Number { get; set; }
public bool NumberRequired { get; set; }
}
Do the necessary in Page_Load
Repeater1.ItemDataBound += new RepeaterItemEventHandler(Repeater1_ItemDataBound);
Repeater1.DataSource = listOfMsts;
Repeater1.DataBind();
Followed by, this where I set ID:
void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var mst = (mst)e.Item.DataItem;
((CheckBox)e.Item.FindControl("cb")).ID = mst.Id.ToString();
}
}
So when the submit button is hit I can loop thru and grab the Id of those checked and save:
protected void Submit(object sender, EventArgs e)
{
foreach (var item in Repeater1.Items)
{
var checkboxes = ((RepeaterItem)item).Controls.OfType<CheckBox>().ToList();
if (checkboxes[0].Checked)
{
Save(checkboxes[0].ID);
....other stuff
}
}
}
You could add an event handler to Repeater.ItemDataBound and create the control within the handler using the reference to the item container.

Resources