I want to get values from dynamically added user control
I'm trying but count comes as 0 so condition failed
Code:
private const string VIEWSTATEKEY = "ContactCount";
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//Set the number of default controls
ViewState[VIEWSTATEKEY] = ViewState[VIEWSTATEKEY] == null ? 1 : ViewState[VIEWSTATEKEY];
//Load the contact control based on Vewstate key
LoadContactControls();
}
}
private void LoadContactControls()
{
for (int i = 0; i < int.Parse(ViewState[VIEWSTATEKEY].ToString()); i++)
{
rpt1.Controls.Add(LoadControl("AddVisaControl.ascx"));
}
}
protected void addnewtext_Click(object sender, EventArgs e)
{
ViewState[VIEWSTATEKEY] = int.Parse(ViewState[VIEWSTATEKEY].ToString()) + 1;
LoadContactControls();
}
EDIT
Here is the problem count takes as 0 so condition failed loop comes out
private void saveData()
{
foreach (var control in rpt1.Controls)
{
var usercontrol = control as VisaUserControl;
string visaNumber = usercontrol.TextVisaNumber;
string countryName = usercontrol.VisaCountry;
}
}
}
protected void Save_Click(object sender, EventArgs e)
{
saveData();
}
.ascx.cs
public string TextVisaNumber
{
get { return txtUser.Text; }
set { txtUser.Text = value; }
}
public string VisaCountry
{
get { return dropCountry.SelectedValue; }
set { dropCountry.SelectedValue = value; }
}
.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="AddVisaControl.ascx.cs" EnableViewState="false" Inherits="Pyramid.AddVisaControl" %>
<%# Register assembly="BasicFrame.WebControls.BasicDatePicker" namespace="BasicFrame.WebControls" tagprefix="BDP" %>
<div id="divreg" runat="server">
<table id="tbl" runat="server">
<tr>
<td>
<asp:Label ID="lbl2" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td> Visa Number:</td>
<td><asp:TextBox ID="txtUser" Width="160px" runat="server"/></td>
<td> Country Name:</td>
<td><asp:DropDownList ID="dropCountry" Width="165px" runat="server"></asp:DropDownList></td>
</tr>
<tr>
<td> Type of Visa:</td>
<td><asp:DropDownList ID="dropVisa" Width="165px" runat="server"></asp:DropDownList></td>
<td> Type of Entry:</td>
<td><asp:DropDownList ID="dropEntry" Width="165px" runat="server"></asp:DropDownList></td>
</tr>
<tr>
<td> Expiry Date</td>
<td><BDP:BasicDatePicker ID="basicdate" runat="server"></BDP:BasicDatePicker></td>
<td>
<asp:Button ID="btnRemove" Text="Remove" runat="server" OnClick="btnRemove_Click" />
</td>
</tr>
</table>
</div>
Any ideas? Thanks in advance
You need to create public property in your user control.
And access that property through the id of the user control.
See this and This question.
Always assign id to the controls you are adding its a good practice.
Control ctrl = Page.LoadControl("~/UserControls/ReportControl.ascx");
ctrl.ID = "UniqueID";
Also since you are adding controls dynamically you need to manage view state of the same, or add third party controls who do this part for you.
Related
Noobie, question, I dont remember !
I created a visual webpart, which creates a user control, I added a repeater in htnml view, and now I need to bind it to data, however I cant seem to find the repeater control in the codebehind.
<table id="engagementletterReport" class="display" border="0">
<thead>
<tr>
<th>JobCode</th>
<th>JobName</th>
</tr>
</thead>
<tbody>
<asp:Repeater runat="server" ID="repeater">
<ItemTemplate>
<tr>
<td>
<%# DataBinder.Eval(Container.DataItem, "JobCode") %>
</td>
<td>
<%# DataBinder.Eval(Container.DataItem, "JobName") %>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</tbody>
</table>
And my webpart
public class EngagementLetterWebPart : WebPart
{
// Visual Studio might automatically update this path when you change the Visual Web Part project item.
private const string _ascxPath = #"~/_CONTROLTEMPLATES/15/xx.SP.xx.WebParts.WebParts/EngagementLetterWebPart/EngagementLetterWebPartUserControl.ascx";
protected override void CreateChildControls()
{
Control control = Page.LoadControl(_ascxPath);
Controls.Add(control);
}
protected override void OnLoad(EventArgs e)
{
BindData();
}
private void BindData()
{
//here, how??
repeater.DataSource = JobContext.GetEngagementLetterReport(SPContext.Current.Site, true, 500, 1);
repeater.DataBind();
}
}
You can bind the repeater using following steps
1.Declare a public variable
Control innerControl;
2.Change the createchildcontrols function as below
protected override void CreateChildControls()
{
innerControl = Page.LoadControl(_ascxPath);
Controls.Add(innerControl);
}
3.Change the BindData function as below
private void BindData()
{
if (innerControl != null)
{
//here, how??
Repeater repeater = innerControl.FindControl("repeater") as Repeater;
if (repeater != null)
{
repeater.DataSource = JobContext.GetEngagementLetterReport(SPContext.Current.Site, true, 500, 1);
repeater.DataBind();
}
}
}
I'am trying to divide all of my products that i listed by using a repeater to pages. For example there are 3 pages. The paging looks well but when i click to next page button it is going to page 4 which is not exist actually. What can be the reason ? Implementation is below.
private void showShoes()
{
dataInThePage = new PagedDataSource()
{
DataSource = ap.getShoes(),
AllowPaging = true,
PageSize = 2,
CurrentPageIndex = pageNo
};
shoeRepeater.DataSource = dataInThePage;
shoeRepeater.DataBind();
pageAmount = dataInThePage.PageCount - 1;
//
pageInfoLabel.Text = "Page: " + (dataInThePage.CurrentPageIndex + 1) + "/" + dataInThePage.PageCount + " - Number of Shoes: " + (dataInThePage.DataSourceCount);
//
previousButton.Enabled = !dataInThePage.IsFirstPage;
nextButton.Enabled = !dataInThePage.IsLastPage;
}
private int pageNo
{
get
{
if (ViewState["pageNumber"] != null)
return Convert.ToInt32(ViewState["pageNumber"]);
return 0;
}
set
{
ViewState["pageNumber"] = value;
}
}
private int pageAmount
{
get
{
if (ViewState["pageNumber"] != null)
return Convert.ToInt32(ViewState["pageNumber"]);
return 0;
}
set { ViewState["pageNumber"] = value; }
}
public PagedDataSource dataInThePage { get; set; }
protected void previousButton_Click(object sender, EventArgs e)
{
pageNo -= 1;
showShoes();
}
protected void nextButton_Click(object sender, EventArgs e)
{
pageNo += 1;
showShoes();
}
Front-end:
<ajaxToolkit:TabPanel ID="TabPanel5" runat="server">
<HeaderTemplate>Show Shoes</HeaderTemplate>
<ContentTemplate runat="server">
<asp:Repeater ID="shoeRepeater" runat="server">
<HeaderTemplate></HeaderTemplate>
<ItemTemplate>
<table border="1" style="border-color:#ff9900; width:400px; font-weight:bold; font-family:'Oswald', Arial, sans-serif;">
<tr>
<td rowspan="6" style="width:150px; height:150px;">
<image src="shoeImages/<%#DataBinder.Eval(Container.DataItem,"ImagePath") %>"></image>
</td>
</tr>
<tr>
<td>
<%#DataBinder.Eval(Container.DataItem,"BrandName") %> - <%#DataBinder.Eval(Container.DataItem,"ModelName") %>
</td>
</tr>
<tr>
<td>
Price: $<%#DataBinder.Eval(Container.DataItem,"Price") %>
</td>
</tr>
<tr>
<td>
Size: <%#DataBinder.Eval(Container.DataItem,"Size") %>
</td>
</tr>
<tr>
<td>
Color: <%#DataBinder.Eval(Container.DataItem,"PrimaryColor") %> - <%#DataBinder.Eval(Container.DataItem,"SecondaryColor") %>
</td>
</tr>
<tr>
<td>
Quantity: <%#DataBinder.Eval(Container.DataItem,"Quantity") %>
</td>
</tr>
</table>
</ItemTemplate>
<FooterTemplate></FooterTemplate>
</asp:Repeater>
<div style="width:600px; height:20px;">
<div style="width:50px; height:100%; float:left">
<asp:Button ID="previousButton" runat="server" OnClick="previousButton_Click" Text="<<" Width="50px"/>
</div>
<div style="width:500px; height:100%; float:left; text-align:center">
<asp:Label ID="pageInfoLabel" runat="server" Text=" "></asp:Label>
</div>
<div style="width:50px; height:100%; float:left">
<asp:Button ID="nextButton" runat="server" OnClick="nextButton_Click" Text=">>" Width="50px"/>
</div>
</div>
</ContentTemplate>
</ajaxToolkit:TabPanel>
I had to guess on a number of things, but I was able to take the posted code and get it to work in VS 2010 using an ASP.NET 4.0 project.
Here are the things I did to get it working:
Add a Shoe POCO with the 8 public properties referenced in the .aspx page (not shown)
Add a FakeShoeRepository class that has a private static List<Shoe> with 9 shoes (not shown)
Add a static method called getShoes() that returns a reference to the private member variable of the repository (not shown)
Set the dataInThePage.DataSource = FakeShoeRepository.getShoes() (not shown)
Add a Page_Load() event
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
pageNo = 0;
showShoes();
}
}
Remove the pageAmount property
Remove the one place pageAmount was being set in the showShoes() method (this was effectively setting ViewState["pageNumber"] = PageCount - 1)
The last two items are where the actual problem was in the provided code.
I want to insert the selected item of drop down list into database but my drop down list keep returns the first option . auto post back is false .
codes here :
dropTask() = drop down list where I populate it from database.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
dropTask();
}
}
protected void AjaxFileUpload1_UploadComplete(object sender, AjaxControlToolkit.AjaxFileUploadEventArgs e)
{
String pathdirectory = (dropListActivity.SelectedItem.Text+"/");
String filepathImage = (pathdirectory + e.FileName);
EnsureDirectoriesExist(pathdirectory);
AjaxFileUpload1.SaveAs(Server.MapPath(filepathImage));
Session["filepathImage"] = filepathImage;
}
i had checked the value return from drop down list using label :
protected void btnDone_Click(object sender, EventArgs e)
{
if (Session["filepathImage"] != null)
{
string filepathImage = Session["filepathImage"] as string;
Label1.Text = filepathImage;
}
}
the label text show the first option of the drop down list value instead of the choice I have chosen . Please enlighten me on this .
ASPX:
<tr>
<td>
<h2>Upload your Story!</h2>
<asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
</asp:ToolkitScriptManager>
</td>
</tr>
<tr>
<td colspan = "2"></td>
</tr>
<tr>
<td>
<b>Select Activity:</b>
</td>
<td>
<asp:DropDownList ID="dropListActivity" runat="server"
onselectedindexchanged="dropListActivity_SelectedIndexChanged">
</asp:DropDownList>
</td>
</tr>
<tr>
<td colspan = "2"></td>
</tr>
<tr>
<td>
<b>Story Title:</b>
</td>
<td>
<asp:TextBox ID="txtStoryTitle" runat="server"
ontextchanged="txtTitle_TextChanged" AutoPostBack="True"></asp:TextBox>
</td>
</tr>
<tr>
<td class="style1">
<b>Upload your files here:</b><br />
Multiple Images and 1 Audio file only.
</td>
<td class="style1">
<asp:AjaxFileUpload ID="AjaxFileUpload1" runat="server"
onuploadcomplete="AjaxFileUpload1_UploadComplete"
/>
</td>
</tr>
<tr>
<td colspan = "2"></td>
</tr>
<tr>
<td>
<asp:Label ID="Label1" runat="server" ></asp:Label>
</td>
<td>
<asp:Button ID="btnDone" runat="server" Text="Done" onclick="btnDone_Click" />
</td>
</tr>
DropListActivity.SelectedItem.ToString should do the trick. There are a few other things you should keep in mind:
Make sure you are not populating the dropdownlist on a postback.
Selected value will only be available at the sever if the portion of
the page containing the dropdownlist control is posted back.i.e if
you are using an update panel your dropdownlist should be present
within that panel or if you are posting back the entire page then there wont be any problem at all provided you meet the first criteria.
Your event handler dropListActivity_SelectedIndexChanged will
always be fired when a page is posted back and the seleceted index
has changed. The event handler dropListActivity_SelectedIndexChanged will be called after the page_load subroutine is executed.
I assume you need something like:
private void SaveSelected()
{
ViewState["SelectedItem"] = dropListActivity.SelectedItem;
}
which you use on dropListActivity_SelectedIndexChanged and
private void LoadSelected()
{
if (ViewState["SelectedItem"] != null)
dropListActivity.SelectedItem = (ListItem)ViewState["SelectedItem"];
}
which you call after dropTask();
Please, refer to this post's answer
in dropListActivity_SelectedIndexChanged event do like
if(dropListActivity.Items.Count > 0)
{
ViewState["DropDownSelectedValue"] = dropListActivity.Item.SelectedValue;
}
and on Load or databind of drop down list event write
if(ViewState["DropDownSelectedValue"] != null && dropListActivity.Items.Count > 0)
{
dropListActivity.SelectedValue = ViewState["DropDownSelectedValue"].ToString();
}
I have a list view which retrieves the data from sql data source. I am trying to make two buttons(Yes and No) and a label outside the list view visible only if the list view is not empty. The process is: a person enter the information into text boxes and click the button retrieve, if the entered data exists in the database, the list view shows certain information.
I have the following code:
protected void btnExistingRetrive_Click(object sender, EventArgs e)
{
if (lstExisting.Items.Count>0 )
{
lblIsITYou.Visible = true;
btnYes.Visible = true;
btnNo.Visible = true;
}
}
By default buttons and the label are not visible.
The problem is when i click on retrieve button it shows me the list view with the information but buttons a the label are still not visible. They became visible only when i double click the retrieve button. Please tell me what is my mistake?
Thank you
Use the ListView EmptyDataTemplate
<asp:ListView ID="ContactsListView"
DataSourceID="ContactsDataSource"
runat="server">
<LayoutTemplate>
<table runat="server" id="tblProducts">
<tr runat="server" id="itemPlaceholder" />
</table>
</LayoutTemplate>
<ItemTemplate>
<tr runat="server">
<td>
<asp:Label ID="FirstNameLabel" runat="Server" Text='<%#Eval("FirstName") %>' />
</td>
<td>
<asp:Label ID="LastNameLabel" runat="Server" Text='<%#Eval("LastName") %>' />
</td>
</tr>
</ItemTemplate>
<EmptyDataTemplate>
<table class="emptyTable" cellpadding="5" cellspacing="5">
<tr>
<td>
<asp:Image ID="NoDataImage"
ImageUrl="~/Images/NoDataImage.jpg"
runat="server"/>
</td>
<td>
No records available.
</td>
</tr>
</table>
</EmptyDataTemplate>
</asp:ListView>
do you bind listview before checking the items count?
Do this on postback instead of in the event.
In your Page_Load do something like this:
protected void Page_Load(object sender, EventArgs e)
{
bool visible = (lstExisting.Items.Count > 0); // assuming it's never null
lblIsITYou.Visible = visible;
btnYes.Visible = visible;
btnNo.Visible = visible;
}
If the above creates complications then do as I said first with postback:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
bool visible = (lstExisting.Items.Count > 0); // assuming it's never null
lblIsITYou.Visible = visible;
btnYes.Visible = visible;
btnNo.Visible = visible;
}
}
The following is the design.
<table>
<tr>
<td>Project Title</td>
<td>Download Link</td>
</tr>
<tr>
<td><asp:Label ID="dlLbl" runat="server"></asp:Label></td>
<td><asp:Label ID="dlLink" runat="server"></asp:Label></td>
</tr>
</table>
And the following is the backend codes.
foreach (SPListItem objInnovationListItem in objInnovationList.Items)
{
if (Convert.ToString(objInnovationListItem["Innovation Approval Status"])== status)
{
countStatus++;
//Displays name of the document and download link
dlLbl.Text = objInnovationListItem["Project Title"].ToString();
dlLink.Text = "<a href='/RIDepartment/Innovation%20Submission/" + objInnovationListItem.File.Name + "'>Download</a><br>";
}
}
Hence, my question is, what can I do to allow the tables to dynamically accommodate the document and dl link when there's more than 1 in the loop?
Appreciate some code samples.
With your code style (manual creating html without web-controls) i recommend you to look on ASP.NET MVC side. But i can answer to your question:
First - you need to use asp:Repeater like this:
<table>
<tr>
<td>Project Title</td>
<td>Download Link</td>
</tr>
<asp:Repeater ID="repLinks" runat="server"
onitemdatabound="repLinks_ItemDataBound">
<ItemTemplate>
<tr>
<td>
<asp:Label ID="lblProject" runat="server" Text="Label"></asp:Label>
</td>
<td>
<asp:HyperLink ID="hlLink" runat="server">HyperLink</asp:HyperLink>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
second: you need to initialize your collection, that you want to display. For example: you want to display a collection of objInnovationListItem class:
public class objInnovationListItem
{
public string Name { get; set; }
public string Title { get; set; }
public override string ToString()
{
return Title;
}
}
you need do next:
// list - it's source List<objInnovationListItem>
var bindList = list.Where(p => objInnovationListItem["Innovation Approval Status"] == status); // filter your collection - replace you foreach and if statement
repLinks.DataSource = bindList; // set to repeater your displayed collection
repLinks.DataBind(); // bind your collection
and last - you need to indicate in your Repeater ItemTemplate how to display your objInnovationListItem instance - subscribe to event of your Repeater ItemDataBound:
protected void repLinks_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
var item = e.Item.DataItem as objInnovationListItem;
((Label) e.Item.FindControl("lblProject")).Text = item.Name;
((HyperLink) e.Item.FindControl("hlLink")).NavigateUrl = string.Format("/downloaduri?id={0}", item.Title);
}
Result will look like that:
I would use a repeater... Something like this (code might not be exact):
<table>
<tr>
<td>Project Title</td>
<td>Download Link</td>
</tr>
<asp:Repeater id="rptItems" runat="server">
<ItemTemplate>
<tr>
<td><asp:Label ID="dlLbl" runat="server"></asp:Label></td>
<td>Download<br></td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
and then in the ItemDataBound event of the repeater, do something like this:
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
((Label)e.Item.FindControl("dlLbl")).Text= ((SPListItem)e.Item.DataItem)["Project Title"].ToString();
}
Why don't you skip the server side controls, and just write the actual html?
Include this div in your aspx file:
<div runat="server" id="divTable"></div>
And put this in your Page_Load():
StringBuilder sb = new StringBuilder();
sb.Append("<table><tr><td>Project Title</td><td>Download Link</td></tr>");
for (int i = 0; i < 10; i++)
{
sb.AppendFormat("<tr><td>{0}</td><td><a href='{1}'>{1}</a></td></tr>", "Title", "Link");
}
sb.Append("</table>");
divTable.InnerHtml = sb.ToString();
You'll of course need to replace "Title" and "Link" with the appropriate values.
Your other options is to actually create new labels and links, but ASP.net is notoriously difficult to work with when you create your server side controls dynamically.