Dynamically create ASPxButtons - c#

I want to create a download list where each available file has its own ASPxButton and I would like to dynamically create them rather than creating like 30 manually and dynamically setting them to visible.
Since I don't have a form within my .aspx.cs file but create my buttons within a table in my .aspx code, I can't use the form.AddButton method. Any ideas on how to do something like that?
Not sure if that helps but here is the code for the 2 buttons I already have:
<dx:TabPage Name="Downloads" Text="Downloads" Enabled="false">
<ContentCollection>
<dx:ContentControl runat="server">
<table class="grid_centered">
<tr>
<td>
<dx:ASPxButton ID="btnDownload0" runat="server" Text="Anschreiben" Theme="Metropolis" CssClass="button centered" OnClick="btn_Click" Width="300px"></dx:ASPxButton>
</td>
</tr>
<tr>
<td>
<dx:ASPxButton ID="btnDownload1" runat="server" Text="Serie 1" Theme="Metropolis" CssClass="button centered" OnClick="btn_Click" Width="300px" Visible="false" Enabled="false"></dx:ASPxButton>
</td>
</tr>
</table>
</dx:ContentControl>
</ContentCollection>
</dx:TabPage>

The solution to this is to use an asp:Repeater. This way, I only have to write the details for one and use the OnItemCommand event to handle button clicks. I had to switch to using asp:Button instead of dx:ASPxButton, though since I needed the CommandName field to pass the info which button was pressed along to my event handler.
<asp:Repeater
ID="MyRepeater"
runat="server"
DataSourceID="MyDataSource"
OnItemCommmand="MyClickedEventHandler">
<ItemTemplate>
<asp:Button
ID="MyButton"
runat="server"
Text="Download"
CommandName='<%# $"{Eval("keyField")}" %>' />
</ItemTemplate>
</asp:Repeater>

I am not too familiar with dx:ASPxButton but I am assuming it would be similar to an aspx:Button. To dynamically create controls you have to create the controls in the Page_Load() event.
protected void Page_Load()
{
//get your files
string targetDirectory = "your directory";
string [] fileEntries = Directory.GetFiles(targetDirectory);
int i = 0;
foreach(string fileName in fileEntries)
{
ASPxButton btn = new Button();
btn.Text = fileName;
btn.ID = "btnDownload" + i.ToString();
btn.CssClass = "button centered";
btn.Attributes.Add("Theme", "Metropolis");
//add any other properties you need
//add the event handler
btn.Click += new EvenHandler(btn_Clik);
form.AddButton(btn);
}
}

Related

FindControl() always returns null from DataList Textbox

I have 8 items in a SQL table with a Description, ItemNumber, and ImagePath.
protected void Page_Load(object sender, EventArgs e)
{
//fill the datalist for the Signs Table
string tCallFrom = "Program." + System.Reflection.MethodBase.GetCurrentMethod().Name;
string tQry = #"SELECT * FROM [js_Signs]";
DataTable tblSigns = objCommMethods.fReturnTableFromQry(clsDBSelect.enumDBSelect.ProjectMaster, tQry, tCallFrom);
SignsList.DataSource = tblSigns;
SignsList.DataBind();
}
I am using a DataList to show all of the items along with a textbox that will allow a user to input the number of items they want:
<asp:DataList ID="SignsList" runat="server" RepeatColumns="4" CellPadding="2" Width="90%" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<table>
<tr>
<th>
<%#DataBinder.Eval(Container.DataItem, "Description") %>
</th>
</tr>
<tr>
<th>
<%#DataBinder.Eval(Container.DataItem, "ItemNumber") %>
</th>
</tr>
<tr>
<td>
<asp:Image ID="SignImage" runat="server" ImageUrl='<%#DataBinder.Eval(Container.DataItem, "ImagePath") %>' />
</td>
</tr>
<tr style="text-align: center;">
<td>
<asp:TextBox ID="txtSignQuantity" runat="server" CssClass="txtBox" BackColor="White" Enabled="true"
type="number" min="0" ToolTip="Please choose quantity of signs needed."/>
</td>
</tr>
<tr>
<td>
<p> </p>
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
<div class="btnGroup">
<div class="btnDiv">
<asp:Button ID="btnSave" runat="server" Text="Save" CssClass="btnSave" Width="90px" Visible="true" OnClick="btnSave_Click"/>
</div>
<div class="btnDiv">
<asp:Button ID="btnCancel" runat="server" Text="Clear" CssClass="btnCancel" Width="90px" Visible="true" OnClick="btnCancel_Click"/>
</div>
</div>
After the saved button is clicked in C# I want to find out the value that a user entered but it is always returning null:
protected void btnSave_Click(object sender, EventArgs e)
{
TextBox txtSignQuantity;
string tempSignQuantity;
try
{
foreach (DataListItem item in SignsList.Items)
{
txtSignQuantity = item.FindControl("txtSignQuantity") as TextBox;
tempSignQuantity = txtSignQuantity.Text;
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
I also checked and the Count of SignsList.Items was 8, so I know that it is retrieving the correct information. Sorry, I've never used a Data List before so I'm not really sure how to go about this...
The short answer is that data binding on postback is causing the problem. Check the Page.IsPostBack property before doing data binding:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//fill the datalist for the Signs Table
string tCallFrom = "Program." + System.Reflection.MethodBase.GetCurrentMethod().Name;
string tQry = #"SELECT * FROM [js_Signs]";
DataTable tblSigns = objCommMethods.fReturnTableFromQry(clsDBSelect.enumDBSelect.ProjectMaster, tQry, tCallFrom);
SignsList.DataSource = tblSigns;
SignsList.DataBind();
}
}
ASP.NET WebForms attempts to abstract away the fact that the control instances that were used to render the page are not the same instances it has when handling postback events. Data binding compounds the abstraction because it has to create controls in response to the DataBind call, and then on postback, recreate them based on the ViewState it saved.
Initializing controls from ViewState happens on the Init event, so when the Load event is fired later in the page lifecycle and you call DataBind on the control, everything it restored gets wiped out and recreated.
As for why you were getting null, it may have been that the controls were wiped out but not recreated; it may have had to do with other event handlers that didn't get rewired after the second data binding.

C# Repeater dynamic Button

I am using repeater to generate the button control.
<asp:Repeater ID="rptDoc" runat="server">
<ItemTemplate>
<div style="...">
<asp:Button ID="btnUpload" runat="server" Text="Button" OnClick="button_Click" />
</div>
</ItemTemplate>
</asp:Repeater>
For example, I can generate 4 buttons. However, how can I implement
the program inside each of the button?
when btnUpload1 clicked, it will upload files into Folder1,
when btnUpload2 clicked, it will upload files into Folder2
I know there is a way that create a Table in the web form, and then
dynamically put the generated button inside the table cells... But I
have lots of DIVs with styling, so I don't want to use a table to
place the dynamic buttons.
Thanks for help.
It works for me now, I used the LinkButton instead of Button.
Also added OnItemCommand="ItemCommand" in repeater.
And finally it will goto ItemCommand event when LinkButton clicked.
It gets the value from CommandArgument which set in dynamic LinkButton
<asp:Repeater ID="rpt" runat="server" OnItemCommand="ItemCommand">
<ItemTemplate>
<asp:LinkButton runat="server" CommandArgument='<%# Eval("lbtnUploadCommandArgument")%>' CommandName="ButtonEvent">Upload Files</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
protected void ItemCommand(Object Sender, RepeaterCommandEventArgs e)
{
string[] arr_Para = ((LinkButton)e.CommandSource).CommandArgument.Split(';');
}
When you dynamically add buttons to the web form, you can track what each button should be doing and then process that URL in a common click event, like the hackish example below.
Dictionary<System.Web.UI.WebControls.Button, string> ButtonToURIMap = new Dictionary<System.Web.UI.WebControls.Button, string>();
private void AddButtonToForm()
{
System.Web.UI.WebControls.Button myWebButton = new System.Web.UI.WebControls.Button();
//Initialize/Style your button here.
myWebButton.Click +=myWebButton_Click;
ButtonToURIMap.Add(myWebButton, "http://www.google.com/");
}
void myWebButton_Click(object sender, EventArgs e)
{
if (sender is System.Web.UI.WebControls.Button)
{
System.Web.UI.WebControls.Button callingButton = (System.Web.UI.WebControls.Button)sender;
if ( ButtonToURIMap.ContainsKey(callingButton))
{
string uri = ButtonToURIMap[callingButton];
//code you execute from here
}
}
}
All you need is below.
in your codebehind
Protected Sub MyPointsRepeater_RowCommand(sender As Object, e As System.Web.UI.WebControls.RepeaterCommandEventArgs) Handles MyPointRepeater.ItemCommand
arg = e.CommandArgument.ToString().Split(";"c)
End Sub
in your Aspx page
<asp:Repeater ID="MyPointRepeater" runat="server">
<ItemTemplate>
<label class="ConferenceName"><%#Eval("Conference Name").ToString()%></label><br />
<label class="RegistrationId"><%#Eval("CPD Points / Hours").Tostring() %></label>
<label class="Type"><%#Eval("Type").ToString()%></label>
<asp:LinkButton ID="lnkCustomize" Text="Download Certificate" CommandName="Customize" CssClass="fontLight"
CommandArgument='<%#Eval("R_Id").Tostring() + ";" + Eval("Conf_Id").Tostring() + ";" + Eval("Reg Id").Tostring() + ";" + Eval("CPD Points / Hours").Tostring() + ";" + Eval("Type").Tostring()%>' runat="server" />
</ItemTemplate>
</asp:Repeater>

Using FindControl to find the contents of an HTML control

I've got this code in the code-behind on my page, which works perfectly fine for a repeater:
protected void AcctAssnRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["PBRConnectionString"].ConnectionString);
con.Open();
{
string str10 = ((HtmlInputText)e.Item.FindControl("txtFlgUpdatedOn")).Value;
}
}
I'm trying to do something similar on another page, but it is telling me that "item" isn't valid:
protected void btnSubmit_OnClick(object sender, EventArgs e)
{
string str10 = ((HtmlInputText)e.Item.FindControl("txtDtSentToCIS")).Value;
}
I'm still a C# n00b, can anyone tell me how to reference the value inside this control? Both pages have a runat="server" on the aspx side, so I would expect that there's a way to do it, I'm sure my syntax just needs adjusting.
Thanks!
EDIT: Here's a piece of the aspx. Maybe I should note that it's all inside a Tab Control.
<div style="width:430px;border:1px solid blue;float:left;">
<asp:Panel ID="Panel3" runat="server" Height="220px" style="float:left; margin-left: 19px"
Width="410px">
<table>
<tr>
<td width="210px">BIL Name:</td>
<td width="200px"><asp:textbox id="txtCISName" runat="server"></asp:textbox></td>
</tr>
<tr>
<td width="210px">Date Sent To BIL:</td>
<td width="200px"><input type="text" id="txtDtSentToCIS" class="datepicker" name="txtDtSentToCIS" runat="server" style="height: 14px; width: 70px" /></td>
</tr>
<tr>
<td width="210px">BIL Sign Off Received:</td>
<td width="200px"><asp:DropDownList ID="cboCISSignOff" runat="server" Height="16px"
AutoPostBack="True" onselectedindexchanged="chkCISSignOff_CheckedChanged">
<asp:ListItem>N</asp:ListItem>
<asp:ListItem>Y</asp:ListItem>
</asp:DropDownList></td>
</tr>
<tr>
<td width="210px"><asp:Label runat="server" Text="BIL Response:" ID="CISResp" /></td>
<td width="200px"><asp:textbox id="txtCISResponse" runat="server"
textmode="MultiLine" rows="9" Width="180px"></asp:textbox></td>
</tr>
</table>
</asp:Panel>
</div>
You should be able to use the ID to reach the control. For ex. a textbox:
<asp:TextBox ID="txtDtSentToCIS" runat="server" />
In your code behind you can do something as
SomeMethod(this.txtDtSentToCIS.Text);
or
string enteredByUser = this.txtDtSentToCIS.Text;
If you want to access repeater containing textbox(es) from outside the repeater, you may code like this:
Iterating the RepeaterItemCollection:
foreach (RepeaterItem item in Repeater1.Items)
{
TextBox txtDtSentToCIS = item.FindControl("txtDtSentToCIS") as TextBox;
}
Or simply accessing through indexer:
TextBox txtDtSentToCIS = Repeater1.Items[1].FindControl("txtDtSentToCIS") as TextBox;
Good luck.
If you are using asp I would suggest that you use an asp Text box.
<asp:TextBox ID="textBoxName" runat="server" />
When the button is clicked and you OnClick method is called you can search for the text box by name and assign the text to your string.
string str10 = textBoxName.text;
You don't really need to use the find control unless that control is buried in another control like a grid view or login view.
What could be happening is that the FindControl method only works for the first control collection in this case the only control contained is "Panel3", try this:
var panel = e.Item.FindControl("Panel3") as Panel;
string str10 = ((HtmlInputText)panel.FindControl("txtFlgUpdatedOn")).Value;
Good luck

How to make a link to show all data

I would like to make a task as follow: show the data as links, I only show 3 rows at beginning, so I Take(3). Then, I want a link "Show all", and when I click on it, it will show the rest of data.
I don't know how to do that. Can anyone help me.
Thanks in advance.
Detail.aspx.cs
vertragsnehmer.DataSource = vertrag.Vertragsnehmer.Take(3).Select(x=> new { x.Id, Name = x.GetFullName(), Typ = x.GetType().Name });
vertragsnehmer.DataBind();
Detail.aspx
<asp:Repeater ID="vertragsnehmer" runat="server">
<ItemTemplate>
<tr>
<td>
<asp:HyperLink NavigateUrl='<%# "~/Redirect.aspx?Id=" + Eval("Id") + "&Typ=" + Eval("Typ") %>' Text='<%# Eval("Name") %>' runat="server"></asp:HyperLink>
</td>
<td> </td>
</tr>
</ItemTemplate>
Try this:
place linkbutton on apsx page:
<asp:LinkButton ID="ShowALL" runat="server" onclick="ShowAll_Click">Show All</asp:LinkButton>
on .cs file:
protected void ShowAll_Click(object sender, EventArgs e)
{
vertragsnehmer.DataSource = vertrag.Vertragsnehmer.Select(x=> new { x.Id, Name = x.GetFullName(), Typ = x.GetType().Name });
vertragsnehmer.DataBind();
}
Can you make showAll button postback and rebind the grid with everything in the onCLick event?

How I use the ItemCommand Event for my ListView in my ASP.NET Application

I have a ASP.NET Application with a ListView. In every Row in my ListView I have a LinkButton that open a new webform "Benutzer.aspx". my Problem is that I don't get the Index of this Row. I use the ItemCommand Event but it not work :(
Here my Code:
ASPX:
...
<ItemTemplate>
<tr runat="server">
<td align="left" ><asp:Label ID="Label1" Text='<%# Eval("Benutzer") %>' runat="server" /></td>
<td align="left"><asp:Label ID="Label2" Text='<%# Eval("eMail") %>' runat="server" /></td>
<td align="left"><asp:Label ID="Label3" Text='<%# Eval("Vorname") %>' runat="server" /></td>
<td align="left"><asp:Label ID="Label4" Text='<%# Eval("Nachname") %>' runat="server" /></td>
<td align="left"><asp:Label ID="Label5" Text='<%# Eval("Telefon") %>' runat="server" /></td>
<td align="left"><asp:LinkButton runat="server" Text="Anzeigen" CommandName="Anzeigen" OnCommand="ListView1_ItemCommand" CommandArgument="myArguments"></asp:LinkButton></td>
</tr>
</ItemTemplate>
...
cs file:
...
protected void ListView1_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if (e.CommandName == "Anzeigen")
{
Label lbText = (Label)e.Item.FindControl("Label2");
string email = lbText.Text;
Session["email"] = email;
Response.Redirect("Benutzer.aspx");
}
}
...
What is the matter :(
tarasov
Try this:
First you need to have the index of the button. So in the html code add this in the CommandArgument of the button to get the index:
CommandArgument='<%# Container.DataItemIndex %>'
Then in the codebehind:
if (e.CommandName == "Anzeigen")
{
Label lbText = ListView1.Item[e.CommandArgument].FindControl("Label2");
string email = lbText.Text;
Session["email"] = email;
Response.Redirect("Benutzer.aspx");
}
Hope I Helped
You cannot find the control because it is contained in the child control collection of another server control:
<tr runat="server">
You need to try to find the control recursively:
Take a look
Better way to find control in ASP.NET
Or you can use this extension method:
public static class ControlExtensions
{
public static Control FindControlRecursively(this Control control, string targetControlID)
{
if (control == null)
{
return null;
}
var ctrl = control.FindControl(targetControlID);
if (ctrl == null)
{
foreach (Control child in control.Controls)
{
ctrl = FindControlRecursively(child, targetControlID);
if (ctrl != null)
{
break;
}
}
}
return ctrl;
}
}
Usage:
var ctrl = e.Item.FindControlRecursively("your control ID");
The code you have furnished is simply fine... "just remove the 'CommandArgument' from your listview property , bcoz..its already have the dataindex you are looking for. By specifying a command argument you are overriding the default one.
So just remove the command argument and your code will work fine... :)
I am a VB programmer Check this method may b it gives you some idea
after binding the list with datasource, In the itemCommand do this
Dim <sometext> As Label = TryCast(e.Item.FindControl("Anzeigen"), Label)
If e.CommandName = "Anzeigen" Then
'do what ever you like
'also you can use <sometext> if you want to extract data from list
'simply use <sometext>.<whatproperty>, you can also store it in sessions like the email you are using.
Session("email") = email
Response.Redirect("Benutzer.aspx");
End If
let me know if it helps you solve your problem.
This is the HTML, then build the OnItemCommand.
<asp:ListView ID="lvFiles" runat="server" DataKeyNames="FileName" OnItemCommand="lvFiles_ItemCommand">
<ItemTemplate>
<tr runat="server">
<td style="width:80px">
<asp:LinkButton runat="server"
ID="SelectEmployeeButton"
Text="Download File"
CommandName='<%#Eval("FileName")%>'
CommandArgument='<%#Eval("FileName")%>' />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
Here is the code behind...
protected void lvFiles_ItemCommand(object sender, ListViewCommandEventArgs e)
{
string v = e.CommandArgument.ToString();
}

Categories