I have a small problem with adding and deleting TableRow
I created a table in my code behind :
private void RemplirTab(){
Table1.Rows.Clear();
/*
* METHODE TO CREATE TABLE
*/
TableHeaderRow ligneEntete = new TableHeaderRow();
TableHeaderCell entete1 = new TableHeaderCell();
entete1.Text = "Identifiant";
TableHeaderCell entete2 = new TableHeaderCell();
entete2.Text = "Description";
TableHeaderCell entete3 = new TableHeaderCell();
entete3.Text = "Prix";
TableHeaderCell entete4 = new TableHeaderCell();
entete3.Text = "Action";
ligneEntete.Cells.Add(entete1);
ligneEntete.Cells.Add(entete2);
ligneEntete.Cells.Add(entete3);
ligneEntete.Cells.Add(entete4);
Table1.Rows.Add(ligneEntete);
foreach (Produit px in listeP)
{
TableRow r = new TableRow();
TableCell colId = new TableCell();
colId.Text = Convert.ToString(px.Id);
TableCell colDescription = new TableCell();
colDescription.Text = px.Description;
TableCell colPrix = new TableCell();
colPrix.Text = Convert.ToString(px.Prix);
TableCell colAction = new TableCell();
// colAction.Text = "<a href='~/PageListeTable.aspx?Id="+px.Id+"'>Supprimer<a>";
HyperLink lienSupr = new HyperLink();
// lienSupr.ID = "lienSupr";
lienSupr.Text = "Supprimer";
lienSupr.NavigateUrl = "~/PageListeTable.aspx?Id=" + px.Id;
colAction.Controls.Add(lienSupr);
r.Cells.Add(colId);
r.Cells.Add(colDescription);
r.Cells.Add(colPrix);
r.Cells.Add(colAction);
Table1.Rows.Add(r);
}
}
in my aspx page I put the code below :
<asp:Table ID="Table1" runat="server">
</asp:Table> <br />
<asp:ValidationSummary ID="ValidationSummary1" runat="server" />
<br />
<asp:Label ID="Label1" runat="server" Text="Id : "
AssociatedControlID="Id"></asp:Label>
<asp:TextBox ID="Id" runat="server" Width="167px"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
ErrorMessage="Champ obligatoir " ControlToValidate="Id">*</asp:RequiredFieldValidator>
<br />
<asp:Label ID="Label2" runat="server" Text="Description :"
AssociatedControlID="Descrip"></asp:Label>
<asp:TextBox ID="Descrip" runat="server"></asp:TextBox>
<br />
<asp:Label ID="Label3" runat="server" Text="Prix :"
AssociatedControlID="prix"></asp:Label>
<asp:TextBox ID="prix" runat="server" Width="165px"></asp:TextBox>
<asp:RangeValidator ID="RangeValidator1" runat="server"
ErrorMessage="Prix erroné " ControlToValidate="prix" MaximumValue="225"
MinimumValue="10" Type="Double">*</asp:RangeValidator>
<br />
<asp:Button ID="Button1" runat="server" Text="Ajouter" onclick="Button1_Click" />
</asp:Content>
in my Page_Load() I call the methode to create a Table :
protected void Page_Load(object sender, EventArgs e)
{
if (listeP == null)
{
listeP = new List<Produit>();
listeP.Add(new Produit(1, "ordi", 200));
Produit p = new Produit(2, "clavier", 20);
listeP.Add(p);
}
string pId = Request["Id"];
if (pId != null)
{
int id = Convert.ToInt32(pId);
int pos = listeP.IndexOf(new Produit(id,null,0));
if(pos!=-1)
listeP.RemoveAt(pos);
}
RemplirTab();
}
the problem is when I try to add an table row using the form the last Delete Link is called lienSupr.NavigateUrl = "~/PageListeTable.aspx?Id=" + px.Id; so the row having the last id is deleting and the new line is creating after
some one can help me to resolve this problem
Related
I am currently working on a dynamic gridview that will allow a user to add or delete rows in order to be saved as database entries later on.
My gridview markup is as such:
<asp:UpdatePanel ID="upAirporterSchedule" runat="server" ChildrenAsTriggers="true" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="gvAirporterSchedule" runat="server" ShowFooter="true" AutoGenerateColumns="false" CssClass="table table-striped table-bordered table-hover dataTable no-footer" OnRowDataBound="gvAirporterSchedule_RowDataBound" OnRowCommand="gvAirporterSchedule_RowCommand">
<Columns>
<asp:TemplateField HeaderText="Location" ItemStyle-Width="25%">
<ItemTemplate>
<asp:DropDownList ID="ddlScheduleLoc" runat="server" CssClass="form-control"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Start Date">
<ItemTemplate>
<div class="input-group">
<asp:TextBox ID="tbxAirporterStartDate" runat="server" CssClass="form-control date-picker" Text='<%# Eval("StartDateColumn") %>'></asp:TextBox>
<span class="input-group-addon">
<i class="fa fa-calendar"></i>
</span>
</div>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="End Date">
<ItemTemplate>
<div class="input-group">
<asp:TextBox ID="tbxAirporterEndDate" runat="server" CssClass="form-control date-picker" Text='<%# Eval("EndDateColumn") %>'></asp:TextBox>
<span class="input-group-addon">
<i class="fa fa-calendar"></i>
</span>
</div>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Departure Time">
<ItemTemplate>
<div class="input-group">
<asp:TextBox ID="tbxAirporterDepTime" runat="server" CssClass="form-control time-picker" Text='<%# Eval("DeptTimeColumn") %>'></asp:TextBox>
<span class="input-group-addon">
<i class="fa fa-clock-o"></i>
</span>
</div>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Duration">
<ItemTemplate>
<asp:TextBox ID="tbxAirporterDuration" runat="server" CssClass="form-control" Text='<%# Eval("DurationColumn") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:Button ID="btnDel" runat="server" CssClass="btn btn-default" Text="Delete" CommandName="DeleteRow" />
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="btnAdd" runat="server" CssClass="btn btn-default" Text="Add Entry" CommandName="AddRow" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
Aside from this grid, I have some other fields in the user control. When I go to save, the user will click a button at the bottom of the user control which will package up the form fields above it and the grid into some classes and shoot this off to the database code to add/update this data.
Page.Validate("AirporterFares");
if (Page.IsValid)
{
try
{
// Save trip information.
SysVarService.SharedRideTrip trip = new SysVarService.SharedRideTrip();
if (_tripID > 0)
trip = Global.sysVarService.GetSharedRideTripByID(_tripID);
trip.isVisible = 1;
trip.productType = ReservationService.ProductType.TOUR;
trip.originStopID = Convert.ToInt32(ddlOrigin.SelectedValue.ToString());
trip.destinationStopID = Convert.ToInt32(ddlDestination.SelectedValue.ToString());
trip.defaultDuration = 0;
trip.effectiveDate = DateTime.Parse(tbxAirporterEffDate.Text.Trim());
trip.startTimeOfDay = new DateTime(trip.effectiveDate.Year, trip.effectiveDate.Month, trip.effectiveDate.Day, 1, 1, 1);
trip.endTimeOfDay = new DateTime(trip.effectiveDate.Year, trip.effectiveDate.Month, trip.effectiveDate.Day, 1, 1, 1);
// Save the two fare information.
SysVarService.SharedRideTrip_ShuttleFare aFare = new SysVarService.SharedRideTrip_ShuttleFare()
{
effectiveDate = trip.effectiveDate,
effectiveTravelDate = trip.effectiveDate,
paxTypeID = 1,
oneWayCost = Foundation.StringFormatter.currencyToDouble(tbxAirporterAdultFare.Text.Trim()),
returnCost = 0.00,
numPax = 1,
Currency = 0
};
SysVarService.SharedRideTrip_ShuttleFare cFare = new SysVarService.SharedRideTrip_ShuttleFare()
{
effectiveDate = trip.effectiveDate,
effectiveTravelDate = trip.effectiveDate,
paxTypeID = 2,
oneWayCost = Foundation.StringFormatter.currencyToDouble(tbxAirporterChildFare.Text.Trim()),
returnCost = 0.00,
numPax = 1,
Currency = 0
};
string status = "";
if (_updating)
status = Global.sysVarService.UpdateAirporterFare(trip, aFare, cFare, GetScheduleEntries());
else
status = Global.sysVarService.AddAirporterFare(trip, aFare, cFare, GetScheduleEntries());
if (!String.IsNullOrEmpty(status))
{
spanErrorMsg.Visible = true;
spanErrorMsg.InnerText = status;
return;
}
}
catch (Exception ex)
{
spanErrorMsg.Visible = true;
spanErrorMsg.InnerText = ex.ToString();
return;
}
Response.Redirect("~/Internal/Admin/Default.aspx?action=Airporter_Fares");
}
When I go to either add or update, I call GetScheduledEntries, which is supposed to loop through the datatable (grabbing it from the viewstate) and convert the templated fields into object properties and stuff these objects in a list.
private List<AdminConfigService.SharedRideTimes> GetScheduleEntries()
{
int idx = 0;
List<AdminConfigService.SharedRideTimes> schedule = new List<AdminConfigService.SharedRideTimes>();
if (gvAirporterSchedule.Rows.Count >= 1)
{
for (int i = 1; i <= gvAirporterSchedule.Rows.Count; ++i)
{
// Get data controls.
DropDownList ddl = (DropDownList)gvAirporterSchedule.Rows[idx].Cells[0].FindControl("ddlScheduleLoc");
TextBox startDate = (TextBox)gvAirporterSchedule.Rows[idx].Cells[1].FindControl("tbxAirporterStartDate");
TextBox endDate = (TextBox)gvAirporterSchedule.Rows[idx].Cells[2].FindControl("tbxAirporterEndDate");
TextBox deptTime = (TextBox)gvAirporterSchedule.Rows[idx].Cells[3].FindControl("tbxAirporterDepTime");
TextBox duration = (TextBox)gvAirporterSchedule.Rows[idx].Cells[4].FindControl("tbxAirporterDuration");
schedule.Add(new AdminConfigService.SharedRideTimes()
{
StartDate = DateTime.Parse(startDate.Text.Trim()),
EndDate = DateTime.Parse(endDate.Text.Trim()),
DepartureTime = DateTime.Parse(deptTime.Text.Trim()),
Duration = Convert.ToInt32(duration.Text.Trim()),
EffectiveDates = "",
StopID = Convert.ToInt32(ddl.SelectedValue.ToString())
});
idx++;
}
return schedule;
}
else
return schedule;
}
The problem is, if I delete rows from this grid view and then attempt to save the form, the datatable from the viewstate is bringing back those deleted rows and acting like they are still existing for saving, even though the gridview and the datatable do not have that row anymore (when the DeleteRow command goes through).
else if (e.CommandName == "DeleteRow")
{
SetRowData();
if (ViewState["AirporterScheduleTable"] != null)
{
DataTable dt = (DataTable)ViewState["AirporterScheduleTable"];
DataRow currentRow = null;
GridViewRow gvr = (GridViewRow)(((Button)e.CommandSource).NamingContainer);
int idx = gvr.RowIndex;
if (dt.Rows.Count > 1)
{
dt.Rows.Remove(dt.Rows[idx]);
currentRow = dt.NewRow();
ViewState["AirporterScheduleTable"] = dt;
gvAirporterSchedule.DataSource = dt;
gvAirporterSchedule.DataBind();
SetPreviousData();
}
}
}
private void SetPreviousData()
{
int idx = 0;
if (ViewState["AirporterScheduleTable"] != null)
{
DataTable dt = (DataTable)ViewState["AirporterScheduleTable"];
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; ++i)
{
// Get data controls.
DropDownList ddl = (DropDownList)gvAirporterSchedule.Rows[idx].Cells[0].FindControl("ddlScheduleLoc");
TextBox startDate = (TextBox)gvAirporterSchedule.Rows[idx].Cells[1].FindControl("tbxAirporterStartDate");
TextBox endDate = (TextBox)gvAirporterSchedule.Rows[idx].Cells[2].FindControl("tbxAirporterEndDate");
TextBox deptTime = (TextBox)gvAirporterSchedule.Rows[idx].Cells[3].FindControl("tbxAirporterDepTime");
TextBox duration = (TextBox)gvAirporterSchedule.Rows[idx].Cells[4].FindControl("tbxAirporterDuration");
ddl.SelectedValue = dt.Rows[i]["LocColumn"].ToString();
startDate.Text = dt.Rows[i]["StartDateColumn"].ToString();
endDate.Text = dt.Rows[i]["EndDateColumn"].ToString();
deptTime.Text = dt.Rows[i]["DeptTimeColumn"].ToString();
duration.Text = dt.Rows[i]["DurationColumn"].ToString();
idx++;
}
}
}
}
private void SetRowData()
{
int idx = 0;
if (ViewState["AirporterScheduleTable"] != null)
{
DataTable current = (DataTable)ViewState["AirporterScheduleTable"];
DataRow currentRow = null;
if (current.Rows.Count > 0)
{
for (int i = 1; i <= current.Rows.Count; ++i)
{
// Get data controls.
DropDownList ddl = (DropDownList)gvAirporterSchedule.Rows[idx].Cells[0].FindControl("ddlScheduleLoc");
TextBox startDate = (TextBox)gvAirporterSchedule.Rows[idx].Cells[1].FindControl("tbxAirporterStartDate");
TextBox endDate = (TextBox)gvAirporterSchedule.Rows[idx].Cells[2].FindControl("tbxAirporterEndDate");
TextBox deptTime = (TextBox)gvAirporterSchedule.Rows[idx].Cells[3].FindControl("tbxAirporterDepTime");
TextBox duration = (TextBox)gvAirporterSchedule.Rows[idx].Cells[4].FindControl("tbxAirporterDuration");
currentRow = current.NewRow();
current.Rows[i - 1]["LocColumn"] = ddl.SelectedValue;
current.Rows[i - 1]["StartDateColumn"] = startDate.Text;
current.Rows[i - 1]["EndDateColumn"] = endDate.Text;
current.Rows[i - 1]["DeptTimeColumn"] = deptTime.Text;
current.Rows[i - 1]["DurationColumn"] = duration.Text;
idx++;
}
ViewState["AirporterScheduleTable"] = current;
}
}
}
There doesn't seem to be any where in the code that I am not updating the ViewState datatable when I either delete or add entries to this dynamic gridview. What could be causing the difference in ViewStates? Does the full postback of the button outside of the UpdatePanel and GridView have a different ViewState?
I also pretty much followed this tutorial exactly.
Turned out to be one of those cases where you overlook something simple. When I was populating the grid with data on load, I did not protect it with a
if (!Page.IsPostback)
Because of that, every time the row was deleted, it would refill the data table with the data on Page Load and cause the weird issues where deleted rows didn't seem to be getting deleted.
I have a problem. I created a couple of custom DataControlFields because I need to display data that doesn't come from a DataSource on a DataGrid.
I managed to get the controls unto the GridView but I can't manage to solve a couple of issues.
My controls do not persist their values between postbacks. I have the markup sitting inside an UpdatePanel which I set to Conditional. I then configured my triggers, excluding those of the GridView. I also tried setting the UpdateMode to Always. I get the same behavior here.
Here is my markup:
<asp:UpdatePanel UpdateMode="Conditional" ID="reportchooserUpdatePanel" runat="server">
<ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="ddlMonth" EventName="Load" />
<asp:PostBackTrigger ControlID="ddlMonth" EventName="SelectedIndexChanged" />
<asp:PostBackTrigger ControlID="ddlYear" EventName="DataBinding" />
<asp:PostBackTrigger ControlID="ddlYear" EventName="SelectedIndexChanged
<asp:PostBackTrigger ControlID="GenerateReportsButton" EventName="Click" />
</Triggers>
<table class="ms-formtable">
<tr>
<td class="ms-formlabel">
<asp:Label ID="MonthYearLabel" runat="server" Text=""></asp:Label>
</td>
<td class="ms-formbody align-right">
<asp:DropDownList OnSelectedIndexChanged="ddlMonth_SelectedIndexChanged" AutoPostBack="true" runat="server" ID="ddlMonth" OnLoad="ddlMonth_Load">
<asp:ListItem Value="1">Januar</asp:ListItem>
<asp:ListItem Value="2">Februar</asp:ListItem>
<asp:ListItem Value="3">März</asp:ListItem>
<asp:ListItem Value="4">April</asp:ListItem>
<asp:ListItem Value="5">Mai</asp:ListItem>
<asp:ListItem Value="6">Juni</asp:ListItem>
<asp:ListItem Value="7">Juli</asp:ListItem>
<asp:ListItem Value="8">August</asp:ListItem>
<asp:ListItem Value="9">September</asp:ListItem>
<asp:ListItem Value="10">Oktober</asp:ListItem>
<asp:ListItem Value="11">November</asp:ListItem>
<asp:ListItem Value="12">Dezember</asp:ListItem>
</asp:DropDownList>
</td>
<td class="ms-formbody align-right">
<asp:DropDownList OnSelectedIndexChanged="ddlYear_SelectedIndexChanged" AutoPostBack="true" OnDataBinding="ddlYear_DataBinding" ID="ddlYear" runat="server"></asp:DropDownList>
</td>
</tr>
<tr>
<td style="width:100%;" class="ms-formbody" colspan="3">
<asp:GridView AutoGenerateColumns="false" ShowHeaderWhenEmpty="true" CssClass="grid-view" Width="100%" ID="gvProjects" runat="server">
</asp:GridView>
</td>
<td></td>
<td></td>
</tr>
<tr>
<td class="ms-formtoolbar align-right" colspan="3">
<asp:HyperLink Target="_blank" Font-Size="X-Small" ID="hlGembox" NavigateUrl="http://www.gemboxsoftware.com/spreadsheet/free-version" runat="server"></asp:HyperLink>
<asp:Button OnClientClick="AddNotification('Please wait...')" ID="GenerateReportsButton" runat="server" Text="" OnClick="GenerateReportsButton_Click" />
</td>
<td></td>
<td></td>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
And here is the code of one of my custom DataControlFields. They are basically the same except for the controls they display:
class TemplateDropDownControl : DataControlField
{
SPList reportslist = ListItemHelper.GetReportsList();
protected void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState)
{
string ID = Guid.NewGuid().ToString();
DropDownList list = new DropDownList();
list.ID = ID;
FillContentTypeDropDown(list);
cell.Controls.Add(list);
}
public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
{
//Call the base method.
base.InitializeCell(cell, cellType, rowState, rowIndex);
this.InitializeDataCell(cell, rowState);
}
protected override DataControlField CreateField()
{
return new BoundField();
}
public string DataField
{
get
{
object value = base.ViewState["DataField"];
if (value != null)
{
return value.ToString();
}
else
{
return string.Empty;
}
}
set
{
base.ViewState["DataField"] = value;
this.OnFieldChanged();
}
}
public override void ExtractValuesFromCell(System.Collections.Specialized.IOrderedDictionary dictionary, DataControlFieldCell cell, DataControlRowState rowState, bool includeReadOnly)
{
DropDownList list = cell.Controls[0] as DropDownList;
ListItem selectedValue = list.SelectedItem;
if (dictionary.Contains(DataField))
dictionary[DataField] = selectedValue.Value;
else
dictionary.Add(DataField, selectedValue.Value);
}
private void FillContentTypeDropDown(DropDownList ddlContentTypes)
{
if (reportslist == null)
return;
SPContentTypeCollection cts = reportslist.ContentTypes;
ddlContentTypes.Items.Clear();
foreach (SPContentType ct in cts)
{
ddlContentTypes.Items.Add(new ListItem() { Text = ct.Name, Value = ct.DocumentTemplateUrl + ct.DocumentTemplate.Replace("~site", "") });
}
}
}
And lastly, here is the code where I add these to my page. I set the AutoGenerateColumns property of the GridView to false in markup:
private void BindDataGrid()
{
DataTable table = new DataTable();
table = new DataTable();
table.Columns.Add(ResourceHelper.LoadResource(ResourceName.ProjectnumberTableString));
table.Columns.Add(ResourceHelper.LoadResource(ResourceName.TemplateString));
table.Columns.Add(ResourceHelper.LoadResource(ResourceName.FileFormatString));
gvProjects.Columns.Clear();
gvProjects.DataSource = null;
//Fill DataTable here...
BoundField projectnumberField = new BoundField();
projectnumberField.HeaderText = ResourceHelper.LoadResource(ResourceName.ProjectnumberTableString);
projectnumberField.DataField = ResourceHelper.LoadResource(ResourceName.ProjectnumberTableString);
FileFormatCheckboxControl checkBoxControl = new FileFormatCheckboxControl();
checkBoxControl.DataField = ResourceHelper.LoadResource(ResourceName.FileFormatString);
checkBoxControl.HeaderText = ResourceHelper.LoadResource(ResourceName.FileFormatString);
TemplateDropDownControl dropDownControl = new TemplateDropDownControl();
dropDownControl.DataField = ResourceHelper.LoadResource(ResourceName.TemplateString);
dropDownControl.HeaderText = ResourceHelper.LoadResource(ResourceName.TemplateString);
gvProjects.Columns.Add(projectnumberField);
gvProjects.Columns.Add(dropDownControl);
gvProjects.Columns.Add(checkBoxControl);
gvProjects.DataSource = table;
gvProjects.DataBind();
}
Anybody know what I'm doing wrong here?
EDIT: Maybe I should be mentioning that I display the form in a Sharepoint modal dialog.
Ok I solved it another way since I had not idea why my problem kept happening. I just use a asp:Table now and generate the whole thing from code-behind. I have one method for this which I call on every page postback. It's important to note to call this method only from Page_Load. It didn't work when I called it from Page_Init.
Here is my code:
private void BindDataGrid()
{
GenerateReportsButton.Enabled = true;
reportsTable.Rows.Clear();
TableHeaderRow headerrow = new TableHeaderRow();
TableHeaderCell pnumberheader = new TableHeaderCell();
TableHeaderCell templateheader = new TableHeaderCell();
TableHeaderCell fileFormatHeader = new TableHeaderCell();
pnumberheader.Text = ResourceHelper.LoadResource(ResourceName.ProjectnumberTableString);
templateheader.Text = ResourceHelper.LoadResource(ResourceName.TemplateString);
fileFormatHeader.Text = ResourceHelper.LoadResource(ResourceName.FileFormatString);
headerrow.Cells.Add(pnumberheader);
headerrow.Cells.Add(templateheader);
headerrow.Cells.Add(fileFormatHeader);
reportsTable.Rows.Add(headerrow);
if (ddlYear.SelectedItem == null || ddlMonth.SelectedItem == null)
{
int index = reportsTable.Rows.Add(new TableRow());
TableCell cell = new TableCell();
cell.ColumnSpan = 3;
cell.Text = ResourceHelper.LoadResource(ResourceName.NoListItemsForMonthYear);
reportsTable.Rows[index].Cells.Add(cell);
GenerateReportsButton.Enabled = false;
return;
}
//Get items here
if (items.Count == 0)
{
int index = reportsTable.Rows.Add(new TableRow());
TableCell cell = new TableCell();
cell.ColumnSpan = 3;
cell.Text = ResourceHelper.LoadResource(ResourceName.NoListItemsForMonthYear);
reportsTable.Rows[index].Cells.Add(cell);
GenerateReportsButton.Enabled = false;
return;
}
else
InsertRowIntoProjectTable("Intern", "Intern");
List<string> processedReports = new List<string>();
foreach(SPListItem item in items)
{
if (item[Variables.projectNumberField].ToString() != "Intern" && !processedReports.Contains(item[Variables.activityProject].ToString()))
{
InsertRowIntoProjectTable(item[Variables.activityProject].ToString(), item.ID.ToString());
processedReports.Add(item[Variables.activityProject].ToString());
}
}
}
Then you can just read the data like this:
foreach(TableRow row in reportsTable.Rows)
{
//Important since foreach also iterates over headerrow
if (row.Cells[1].Controls.Count > 0 && row.Cells[1].Controls[0] is DropDownList)
{
string value1= row.Cells[0].Text;
string value2= ((DropDownList)row.Cells[1].Controls[0]).SelectedValue;
//do stuff with the data
}
}
If anybody still finds the answer to my specific problem above, feel free to add it. I will mark it as accepted once verified that it works.
What is up with my spacing here? When the labels contain text the spacing is fine but then they are empty they have white space between each label. Why is extra space being added when the labels contain empty text?
With text in labels (what I want it to look like):
With no text in labels (how I do not want it to look like):
On the C# code behind side:
// On page load
for (int i = 1; i < 10; i++)
{
string ID = i.ToString();
PopulateLastNameLabel(ID);
}
protected void PopulateLastNameLabel(string ID)
{
Label lbl = new Label();
lbl.Width = 70;
lbl.Height = 20;
lbl.Text = "";
lbl.BackColor = System.Drawing.Color.Red;
lbl.ID = "lastname_" + ID;
pnlLastNameLabel.Controls.Add(lbl);
}
On the ASP.NET side:
<asp:Table ID="tblDisplayTable" runat="server">
<asp:TableRow>
<asp:TableCell>
<asp:Panel ID="pnlPrizeNumberLabel" runat="server" Width="80px"></asp:Panel>
</asp:TableCell>
<asp:TableCell HorizontalAlign="Center" VerticalAlign="Middle">
<asp:Panel ID="pnlPrizeDropDownList" runat="server" Width="130px"></asp:Panel>
</asp:TableCell>
<asp:TableCell>
<asp:Panel ID="pnlNickNameLabel" runat="server" Width="70px"></asp:Panel>
</asp:TableCell>
<asp:TableCell>
<asp:Panel ID="pnlPrizeNicknameTextBox" runat="server" Width="125px"></asp:Panel>
</asp:TableCell>
<asp:TableCell>
<asp:Panel ID="pnlFirstNameLabel" runat="server" Width="70px"></asp:Panel>
</asp:TableCell>
<asp:TableCell>
<asp:Panel ID="pnlLastNameLabel" runat="server" Width="70px"></asp:Panel>
</asp:TableCell>
<asp:TableCell>
<asp:Panel ID="pnlEmailAddressLabel" runat="server" Width="140px"></asp:Panel>
</asp:TableCell>
<asp:TableCell>
<asp:Panel ID="pnlAddButton" runat="server" Width="40px"></asp:Panel>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
If I understand you question correctly, you need the following css (remove height from code behind).
The problem each control is in own table cell, so they won't horizontal align properly. So you need to set height explicitly for each control.
<style type="text/css">
td div { margin-right: 5px; }
td div input {border: 1px solid #828282; height: 21px; }
td div span { height: 25px; line-height: 25px; }
</style>
<asp:Table ID="tblDisplayTable" runat="server" CellPadding="0" CellSpacing="0">
<asp:TableRow>
<asp:TableCell>
<asp:Panel ID="pnlPrizeNumberLabel" runat="server" Width="80px">
</asp:Panel>
</asp:TableCell>
<asp:TableCell HorizontalAlign="Center" VerticalAlign="Middle">
<asp:Panel ID="pnlPrizeDropDownList" runat="server" Width="130px">
</asp:Panel>
</asp:TableCell>
<asp:TableCell>
<asp:Panel ID="pnlNickNameLabel" runat="server" Width="70px">
</asp:Panel>
</asp:TableCell>
<asp:TableCell>
<asp:Panel ID="pnlPrizeNicknameTextBox" runat="server" Width="125px">
</asp:Panel>
</asp:TableCell>
<asp:TableCell>
<asp:Panel ID="pnlFirstNameLabel" runat="server" Width="70px">
</asp:Panel>
</asp:TableCell>
<asp:TableCell>
<asp:Panel ID="pnlLastNameLabel" runat="server" Width="70px">
</asp:Panel>
</asp:TableCell>
<asp:TableCell>
<asp:Panel ID="pnlEmailAddressLabel" runat="server" Width="140px">
</asp:Panel>
</asp:TableCell>
<asp:TableCell>
<asp:Panel ID="pnlAddButton" runat="server" Width="40px">
</asp:Panel>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
protected void Page_Load(object sender, EventArgs e)
{
for (int i = 1; i < 10; i++)
{
string ID = i.ToString();
TextBoxLabel(ID);
PopulatePrizeNicknameLabel(ID);
PopulateFirstNameLabel(ID);
PopulateLastNameLabel(ID);
}
}
protected void TextBoxLabel(string ID)
{
TextBox lbl = new TextBox();
lbl.Width = 65;
lbl.Text = "";
lbl.ID = "TextBox_" + ID;
lbl.Text = ID;
pnlNickNameLabel.Controls.Add(lbl);
}
protected void PopulatePrizeNicknameLabel(string ID)
{
Label lbl = new Label();
lbl.Width = 125;
lbl.Text = "";
lbl.BackColor = System.Drawing.Color.Green;
lbl.ID = "PrizeNickname_" + ID;
lbl.Text = ID;
pnlPrizeNicknameTextBox.Controls.Add(lbl);
}
protected void PopulateLastNameLabel(string ID)
{
Label lbl = new Label();
lbl.Width = 70;
lbl.Text = "";
lbl.BackColor = System.Drawing.Color.Red;
lbl.ID = "lastname_" + ID;
lbl.Text = ID;
pnlLastNameLabel.Controls.Add(lbl);
}
protected void PopulateFirstNameLabel(string ID)
{
Label lbl = new Label();
lbl.Width = 70;
lbl.Text = "";
lbl.BackColor = System.Drawing.Color.Blue;
lbl.ID = "firstname_" + ID;
lbl.Text = ID;
pnlFirstNameLabel.Controls.Add(lbl);
}
I prefer creating controls one row at a time instead of one column at a time, but that is not OP.
Actually i'm creating web template using asp.net and c#.
in my user control page i have to create the table dynamically. i just read the data from XML file then retrieve the name and number of columns and rows of each table. while i'm creating the table i assign the name and id to each cell. because i have one row including some textbox for adding the data to database. but after i have created the table i can not access to the textbox cells based on id to get their data and insert it to database.
my dynamic table code is:
public void CreateAddDynamicTable()
{
XmlDocument xDocRead = new XmlDocument();
xDocRead.Load(Server.MapPath("ModuleTemp.xml"));
string xModuleName = hid_ChooseModule.Value;
XmlNode xColCounter = xDocRead.SelectSingleNode("ModuleTemp/" + xModuleName + "/List");
int colCount = xColCounter.ChildNodes.Count;
int nonPkCounter = 0;
string[] nonPrimaryKey = new string[100];
string[] nonPkNewDataTemp = new string[100];
for (int i = 1; i <= colCount; i++)
{
if (xDocRead.SelectSingleNode("ModuleTemp/" + xModuleName + "/Add/TableColumn" + i).Attributes.GetNamedItem("IsPrimaryKey").Value == "N")
{
nonPrimaryKey[nonPkCounter] = xDocRead.SelectSingleNode("ModuleTemp/" + xModuleName + "/Add/TableColumn" + i).Attributes.GetNamedItem("Name").Value;
nonPkCounter++;
}
}
ph_Uc_AddModule.Controls.Clear();
// Fetch the number of Rows and Columns for the table
// using the properties
int tblRows = nonPkCounter;
int tblCols = 2;
// Create a Table and set its properties
Table tbl = new Table();
// Add the table to the placeholder control
ph_Uc_AddModule.Controls.Add(tbl);
// Now iterate through the table and add your controls
for (int i = 0; i < tblRows; i++)
{
TableRow tr = new TableRow();
for (int j = 0; j < tblCols; j++)
{
TableCell tc = new TableCell();
Label td_Add_Header = new Label();
TextBox td_Add = new TextBox();
if (j == 0)
{
td_Add_Header.Text = nonPrimaryKey[i];
td_Add_Header.ID = "lb" + (i + 1) + "_header_AddModule";
// Add the control to the TableCell
tc.Controls.Add(td_Add_Header);
tc.CssClass = "td_Header_AddModule";
}
else
{
td_Add.Text = "";
td_Add.ID = "tb" + (i + 1) + "_AddModule";
// Add the control to the TableCell
tc.Controls.Add(td_Add);
tc.CssClass = "td_Tb_AddModule";
}
// Add the TableCell to the TableRow
tr.Cells.Add(tc);
}
// Add the TableRow to the Table
tbl.Rows.Add(tr);
}
}
my user control page which is contain a PlaceHolder is as below:
<asp:Panel ID="pn_Uc_TModule" runat="server">
<asp:Table runat="server" ID="table_Uc_TModule" CssClass="table_Uc_TModule" Width="100%">
<asp:TableRow runat="server" VerticalAlign="Top" Height="50px">
<asp:TableCell runat="server">
<asp:Button runat="server" Text="" CssClass="btn_Add_Active" OnClick="btn_AddNew_Click" />
<asp:Button ID="btn_Cancel_NewItem" runat="server" Text="" CssClass="btn_Cancel_New" OnClick="btn_Cancel_AddNew" Visible="false" />
<asp:Table runat="server" ID="table_Uc_AddModule" Visible="false">
<asp:TableRow runat="server">
<asp:TableCell runat="server" >
<asp:PlaceHolder ID="ph_Uc_AddModule" runat="server">
</asp:PlaceHolder>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow ID="TableRow1" runat="server">
<asp:TableCell runat="server" CssClass="td_Tb_AddModule" HorizontalAlign="Center">
<asp:Button ID="btn_Insert" runat="server" OnClick="Uc_AddModule_ItemInsert" Text="" CssClass="btn_Add" />
<asp:Button ID="btn_Cancel" runat="server" OnClick="Uc_AddModule_Clear" Text="" CssClass="btn_Clear" />
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</asp:Panel>
i'm using below method in my insert function at the code behind to access the data inserted at the textbox:
for (int i = 1; i <= nonPkCounter; i++)
{
TextBox textBox = (ph_Uc_AddModule.FindControl("tb" + i + "_AddModule")) as TextBox;
}
i have tried pn_Uc_TModule.FindControl("tb" + i + "_AddModule") and also This.ph_Uc_AddModule.FindControl("tb" + i + "_AddModule") but still con not get the texbox data to insert it to database.
could you please guide me how to get it done.
appreciate your consideration.
You should call CreateAddDynamicTable on your Init event always. That will make the viewstate make sense and asp.net will load all the values to the controls. Then you can add the textboxes to a collection and access them without using FindControl, just the references, in your Page_Load event.
I have a datalist
<asp:DataList ID="dlstImage" runat="server" RepeatDirection="Horizontal" RepeatColumns="5"
CellSpacing="8">
<ItemTemplate>
<asp:ImageButton ID="Image" runat="server" ImageUrl='<%#"~/Controls/ShowImage.ashx?FileName=" +DataBinder.Eval(Container.DataItem, "FilePath") %>'
OnCommand="Select_Command" CommandArgument='<%# Eval("Id").ToString() +";"+Eval("FilePath")+";"+Eval("Index") %>' /><br />
<asp:Label ID="lbl" runat="server" Text="Figure"></asp:Label><%# dlstImage.Items.Count + 1%>
</ItemTemplate>
</asp:DataList>
In which i am binding the image after uploading through uplodify upload, now i have one more datalist
and two btn up and down,
<asp:ImageButton ID="ibtnMoveUp" runat="server" ImageUrl="~/App_Themes/Default/Images/moveup.bmp"
Style="height: 16px" ToolTip="MoveUp The Item" />
<asp:ImageButton ID="ibtnMoveDown" runat="server" ImageUrl="~/App_Themes/Default/Images/movedown.bmp"
ToolTip="MoveDown The Item" />
<asp:DataList ID="dlstSelectedImages" runat="server" RepeatDirection="Horizontal"
RepeatColumns="5" CellSpacing="8">
<ItemTemplate>
<asp:ImageButton ID="Image" runat="server" /><br />
<asp:Label ID="lbl" runat="server" Text="Figure"></asp:Label><%# dlstImage.Items.Count + 1%>
</ItemTemplate>
</asp:DataList>
My both datalist is in the same webuser control, datalist1 and datalist2 and I have 2 btn up and down, when i select one image from datalist1 and click on down btn then the selected image should move to datalist2. How to do that? someone please help me,
You need to handle the ItemCommand event of one DataList in which you have to copy the selected data (image) into another dataSource of two DataList and remove that item from the datasource of one DataList.
Markup:
<asp:DataList
ID="DataList1"
runat="server"
OnItemCommand="PerformMove"
>
<ItemTemplate>
<br /><%#Eval("Text") %>
<asp:Button ID="btn1"
runat="server"
Text="Move"
CommandName="cmd"
CommandArgument='<%#Eval("Text") %>'
/>
</ItemTemplate>
</asp:DataList>
<asp:DataList ID="DataList2" runat="server">
<ItemTemplate>
<br /><%#Eval("Text") %>
</ItemTemplate>
</asp:DataList>
Code-behind (.cs)
public class Data
{
public string Text { get; set; }
public override int GetHashCode()
{
return Text.GetHashCode();
}
public override bool Equals(object obj)
{
return GetHashCode() == obj.GetHashCode();
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<Data> list1 = new List<Data >()
{
new Data() { Text="One"},
new Data() { Text="Two"},
new Data() { Text="Three"},
};
List<Data> list2 = new List<Data>();
Session["list1"] = list1;
Session["list2"] = list2;
DataList1.DataSource = Session["list1"];
DataList1.DataBind();
DataList2.DataSource = Session["list2"];
DataList2.DataBind();
}
}
protected void PerformMove(object source, DataListCommandEventArgs e)
{
if (e.CommandName == "cmd")
{
List<Data> list1 = Session["list1"] as List<Data>;
List<Data> list2 = Session["list2"] as List<Data>;
list1.Remove(new Data() { Text=e.CommandArgument.ToString() });
list2.Add(new Data() { Text = e.CommandArgument.ToString() });
DataList1.DataSource = Session["list1"];
DataList1.DataBind();
DataList2.DataSource = Session["list2"];
DataList2.DataBind();
}
}
I am using this code and its working well for me.
ArrayList ImgArry = new ArrayList();
path = objGetBaseCase.GetImages(TotImgIds);
ImgArry.Add(SelImgId);
ImgArry.Add(SelImgpath);//image name
ImgArry.Add(SelImgName);//image path
//path.Remove(ImgArry);
List<ArrayList> t = new List<ArrayList>();
if (newpath.Count > 0)
t = newpath;
t.Add(ImgArry);
newpath = t;
for (int i = 0; i < newpath.Count; i++)
{
ArrayList alst = newpath[i];
newtb.Rows.Add(Convert.ToInt32(alst[0]), alst[1].ToString(), alst[2].ToString(), i);
}
dlstSelectedImages.DataSource = newtb;
DataBind();
path = objGetBaseCase.GetImages(TotImgIds);
for (int i = 0; i < path.Count; i++)
{
ArrayList alst = path[i];
tb.Rows.Add(Convert.ToInt32(alst[0]), alst[1].ToString(), alst[2].ToString(), i);
}
dlstImage.DataSource = tb;
DataBind();