How to place a hyperlink field in a web page at runtime? - asp.net

I am trying to display contents of a folder in a hyperlink. I am using masterpage also. The hyperlinks are not shown into the content page. what to do for that?
I know in windows forms we can use like
TextBox.Location=new Point(100,100);
But how to do in web page...please anybody suggest me..
my coding in page_load is
protected void Page_Load(object sender, EventArgs e)
{
DirectoryInfo di = new DirectoryInfo(Server.MapPath("~/ProjectsUpload"));
int i = 0;
foreach (FileInfo fi in di.GetFiles())
{
HyperLink HL = new HyperLink();
HL.ID = "HyperLink" + i++;
HL.Text = fi.Name;
HL.NavigateUrl = "downloading.aspx?file=" + fi.Name;
Page.Controls.Add(HL);
Page.Controls.Add(new LiteralControl("<br/>"));
}
}

You can't add it directly to Page.Controls. You have to add it to the ContentPlaceHolder on the page.

Instead of dynamically creating controls, which is rather messy and error-prone, have you considered using an asp:Repeater control and binding the files directly to it? Something like:
<asp:Repeater ID="RepeaterFiles" runat="server">
<ItemTemplate>
<asp:HyperLink runat="server" Text='<%# Container.DataItem %>'
NavigateUrl='<%# String.Format("downloading.aspx?file={0}", Container.DataItem)%>' />
<br />
</ItemTemplate>
</asp:Repeater>
and in code behind:
DirectoryInfo di = new DirectoryInfo(Server.MapPath("~/ProjectsUpload"));
RepeaterFiles.DataSource = di.GetFiles();
RepeaterFiles.DataBind();
That way you can use declarative mark-up to control layout and keep the logic in your code-behind.

Put a PlaceHolder control on your page:
<asp:PlaceHolder runat="server" ID="ph" />
In your code behind write like:
HyperLink HL = new HyperLink();
HL.ID = "HyperLink" + i++;
HL.Text = fi.Name;
HL.NavigateUrl = "downloading.aspx?file=" + fi.Name;
ph.Controls.Add(HL);
ph.Controls.Add(new Literal { Text = "<br/>"});
I'm making use of the newly C# 3 feature on that last line to set the Text property.

Have you used the debugger to step through the loop to verify that it processes at least one file?
Instead of adding the links to Page.Controls, you could put a list control on the page, and then add each link within a list item. Then you'd know precisely where on the page they should appear.

Create a Panel or a Label in the Page's Content area, and add your HyperLinks into the Controls collection of the Panel.
(Stepping through the code to check whether the IIS App actually enumerates any files in the directory would help too.)

Related

ASPxGridview get row data from server-side

I'm working on a DevExpress Gridview and I want to get the data of the selected row (only one row can be selected at the time). I'm working on the Server-Side and I'm using FocusedRowChanged function.
EDIT: The FocusedRowChanged fire but nothing happen and the textboxes do not change value
protected void dxgrDepartement_FocusedRowChanged(object sender, EventArgs e)
{
Page.ClientScript.RegisterClientScriptBlock(GetType(), "FetchData", "<script language='javascript'>FetchData('4654654646')</script>");
txtDescription.Text = "patate";
//txtComments.Text = dxgrDepartement.GetRowValues(dxgrDepartement.FocusedRowIndex, "IdDepartment").ToString();
}
And the "FetchData :
function FetchData(text) {
//ClearField();
document.getElementById("<%= txtDescription.ClientID %>").value = text.toString();
}
BTW - Changing the callbacks property made no difference for us. We needed callbacks for other functionality so couldn't turn this off anyway.
The GetRowValues method did not work either.
This is a technique described on DevExpress' web site and it worked for us as long as we didnt use DevExpress' controls (ASPxDateEdit, ASPxTextBox):
ASPX page:
<dxwgv:GridViewDataTextColumn Caption="Dist. %" FieldName="DistributionPerc" VisibleIndex="3"
Width="50px">
<DataItemTemplate>
<asp:TextBox ID="txtDistPerc" runat="server" Text='<%# Eval("DistributionPercent") %>'
Width="50px" />
</DataItemTemplate>
</dxwgv:GridViewDataTextColumn>
Code behind:
for (int i = 0; i < grdHistory.VisibleRowCount; i++)
{
TextBox textbox = grdHistory.FindRowCellTemplateControl(i, grdHistory.Columns["DistributionPerc"] as GridViewDataColumn, "txtDistPerc") as TextBox;
var anything = textbox.Text;
}
Use:
gridView.GetRowValues(gridView.FocusedRowIndex, columnFieldName1, columnFieldName2, ..., columnFieldNameN)
Method ASPxGridView.GetRowValues
Property ASPxGridView.FocusedRowIndex
grid.EnableCallback = false; solved my problems!

Juice UI - Textbox inside accordion issue

I'm unable to retrieve the content of a textbox that's inside an accordion panel. My markup is as follows:
<juice:Accordion ID="Accordion1" runat="server">
<juice:AccordionPanel ID="AccordionPanel1" runat="server" Title="Media ID">
<PanelContent>
<asp:Label ID="LabelMediaID" runat="server" Text="Media ID" AssociatedControlID="TextBoxMediaID"></asp:Label>
<asp:TextBox ID="TextBoxMediaID" runat="server"></asp:TextBox>
</PanelContent>
</juice:AccordionPanel>
My server side code is triggered when the user clicks a button:
protected void ButtonSearch_Click(object sender, EventArgs e)
{
// Retrieve controls within accordion panels
TextBox TextBoxMediaID = (TextBox)AccordionPanel1.FindControl("TextBoxMediaID");
string mediaID= "abc";
if (TextBoxMediaID != null)
mediaID= TextBoxMediaID.Text;
I'm able to successfully retrieve my textbox control but when I try to access its Text property it's always empty.
Can someone help me? I'm afraid I'm reasonably new to the world of ASP.NET, Juice etc. Thanks.
It turned out that my problem was caused by having an ASP.NET project that used master pages.
If you're not using master pages then
TextBox TextBox1 = (TextBox)AccordionPanel1.FindControl("TextBox1");
string content= Request.Form[TextBox1.UniqueId];
works perfectly. However, when using a master page with a ContentPlaceHolder then use the following code:
ContentPlaceHolder cph = (ContentPlaceHolder)Master.FindControl("MainContent");
TextBox TextBox1 = (TextBox)AccordionPanel1.FindControl("TextBox1");
string content= Request.Form[cph.UniqueID + "$" + TextBox1.UniqueId];
Hopefully this will save someone a lot of time!
Option 1 - Quick fix
For your page, make ClientIDMode="static" in page directive and then use Request.Form["TextBoxMediaID"] to get value of your text box.
Option 2 - Debug
Go to debug mode and try AccordionPanel1.Controls[0].("TextBoxMediaID"); or AccordionPanel1.Controls[0].Controls[0].("TextBoxMediaID"); because you don't know how many server side controls are there. Simple solution would be to use find control recursive function.

Converting client side html radio buttons to asp.net web controls with dynamic ids. (ASP.net)(VB)

I have the following client side code in .aspx page within a datalist itemtemplate that takes questions from the database like this:
<Itemtemplate>
<b> <%=GetQuestionNum()%>)
<%#Server.HtmlEncode(Eval("Text").ToString())%></b>
<br />
<asp:Panel ID="A" runat="server" Visible='<%#GetVisible(Eval("OptionA").Tostring())%>'>
<input name="Q<%#Eval("ID")%>" type="radio" value="A">
<%#Server.HtmlEncode(Eval("OptionA").ToString())%>
</option><br />
</asp:Panel>
<asp:Panel ID="B" runat="server" Visible='<%#GetVisible(Eval("OptionB").Tostring())%>'>
<input name="Q<%#Eval("ID")%>" type="radio" value="B">
<%#Server.HtmlEncode(Eval("OptionB").ToString())%>
</option><br />
</asp:Panel>
<asp:Panel ID="C" runat="server" Visible='<%#GetVisible(Eval("OptionC").Tostring())%>'>
<input name="Q<%#Eval("ID")%>" type="radio" value="C">
<%#Server.HtmlEncode(Eval("OptionC").ToString())%>
</option><br />
</asp:Panel>
<asp:Panel ID="D" runat="server" Visible='<%#GetVisible(Eval("OptionD").Tostring())%>'>
<input name="Q<%#Eval("ID")%>" type="radio" value="D">
<%#Server.HtmlEncode(Eval("OptionD").ToString())%>
</option><br />
</asp:Panel></itemtemplate>
The output is like:
1) What is your age group?
- Option 1
- Option 2
- Option 3
- Option 4
The ID's of the radio buttons are dynamic ("Q" & QuestionID). If there is no answer to a question then the GetVisible function returns false and the containing panel is hidden.
I have been trying to get rid of the html and replace these with asp:radiobuttons but it is not possible to set id's from databinding.. only simply. I was trying something like:
<asp:RadioButton ID="Q<%#Eval("ID")%>" runat="server" Visible='<%#GetVisible(Eval("OptionA").Tostring())%>'
Text='<%#Server.HtmlEncode(Eval("OptionA").ToString())%>' />
Here is the function that provides data:
Public Shared Function GetQuestionsForSurvey(ByVal id As Integer) As DataSet
Dim dsQuestions As DataSet = New DataSet()
Try
Using mConnection As New SqlConnection(Config.ConnectionString)
Dim mCommand As SqlCommand = New SqlCommand("sprocQuestionSelectList", mConnection)
mCommand.CommandType = CommandType.StoredProcedure
Dim myDataAdapter As SqlDataAdapter = New SqlDataAdapter()
myDataAdapter.SelectCommand = mCommand
mCommand.CommandType = CommandType.StoredProcedure
mCommand.Parameters.AddWithValue("#id", id)
myDataAdapter.Fill(dsQuestions)
mConnection.Close()
Return dsQuestions
End Using
Catch ex As Exception
Throw
End Try
End Function
but I'm finding it impossible to work with the html controls, i.e get their .text value from codebehind, or adding events!
Please can an expert suggest a better way to replace the html with suitable asp.net web controls or from the codebehind and output it. Or point me in the right direction?
Thanks :0)
I had some experience with ASP controls and data binding. The problem you are facing is probably the fact that once you declare a control via markup you can't access it from data binding. Also, you should not confuse the server-side ID with the client-side ID.
The server-side ID, mapped to Id property of controls, is used to programmatically access the control from code behind. Client-side ID is the ID that will be placed in tag's id attribute and is mapped to ClientId property.
Judging from your question, what you need is to build a multi-choice survey, and, in my opinion, it's not important how the IDs are generated, just that they are properly grouped for each question.
I'll answer the part of programmatically accessing controls in data binding, which is a part of your question.
Here is an example from my code. Suppose you have a very simple GridView like this
<asp:GridView ID="example" runat="server" OnRowDataBound="DataBound">
<Columns>
<asp:TemplateField HeaderText="New">
<ItemTemplate>
<asp:Image ID="imgExample" runat="server" />
</ItemTemplate>
</Columns>
</asp:GridView>
It takes a data set during data binding and sets the image according to some property. It works the same as DataList, don't worry.
Now, in code behind, you handle the RowDataBoundEvent. You can't access the imgExample object directly, because it's a child of the ItemTemplate. When the row is bound, you have direct access to the row and then you can use the FindControl method of Control class
Here is C# code example (easy to convert to VB)
protected void DataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow) //Required
{
GridViewRow row = e.Row;
[...] //get an email message
(row.Cells[0].FindControl("imgExample") as Image).ImageUrl = (email.AlreadyRead)
? "Mail_Small.png"
: "Mail_New_Small.png";
}
}
Application to your case
In order to build a multi-choice survey, my advice is to create a DataList that will hold questions (the outer control) and then, for each row, declare a RadioButtonList that holds answers (the inner control). Bind the outer data list to the data set of questions and answers. Handle the RowDataBound event or whatever it's called in the DataList world. When you handle that event, bind the inner radiobuttonlist to the answers.
It should work for you
I am actually working on something similar at the moment. I am using javascript and jQuery to dynamically add controls to my page. After adding them to my page I have to get the new controls, their text, etc. The way I've been doing it is something like this:
<table id='BuilderTable' class="BuilderTable">
<tbody class='BuilderBody'>
</tbody>
</table>
<asp:Button runat="server" ID="saveButton" OnClick="SaveButton_Click" OnClientClick="SaveData()"
Text="Save Form" />
<asp:HiddenField runat="server" ID="controlsData" />
This table is where I put all my new controls.
Then when the client clicks the save button it first calls this javascript / jQuery function:
function SaveData() {
var controlRows = $('#BuilderTable tr.control');
var controls= [];
controlRows.each(function (index) {
//process control information here ...
controlText = //use jQuery to get text, etc...
var control = {
Index: (index + 1),
Text: controlText
};
controls.push(control);
});
var str = JSON.stringify(questions);
$('#<%= controlsData.ClientID %>').val(str);
}
Then the server side function for the button click is called (this in in C#, adapt to VB).
protected void SaveButton_Click(object sender, EventArgs e)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
string str = controlsData.Value;
List<Control> controls = jss.Deserialize<List<Control>>(str);
}
Using a Control class like this:
public class Control
{
public int Index { get; set; }
public string Text { get; set; }
}
This code uses javascript and jQuery to get your controls, JSON to serialize the data and save it in a asp hiddenfield then grab the data server-side and deserialize into objects that your code can use. Then take the data and do whatever you need to.

Getting value in footer template from code behind-Repeater

I have a repeater like this:
<asp:Repeater runat="server" ID="pde">
<HeaderTemplate></HeaderTemplate>
<ItemTemplate>
<asp:Literal runat="server" ID="literal1"></asp:Literal>
</ItemTemplate>
<FooterTemplate><asp:Literal runat="server" ID="literal2"></asp:Literal></FooterTemplate>
</asp:Repeater>
Now in literal2 I want to get the value from code behind.But I am not able to get the literal2 in code behind.Any idea how to get this?
You should be able to access it by accessing the last RepeaterItem in your repeater which will be your footer. Then do a search, using FindControl, on the RepeaterItem for any control you are looking for.
Using your example above do:
Literal controlYouWant = pde.Controls[pde.Controls.Count - 1].FindControl("literal2") as Literal;
You can break down the statements to:
// This will get you the footer
RepeaterItem item = pde.Controls[pde.Controls.Count - 1];
// From here you finds any control you want within the RepeaterItem.
Literal controlYouWant = item.FindControl("literal2") as Literal;
First search through items in repeater and only take the footer item type and discard the others. Take a look to the following code.
foreach(RepeaterItem item in repeterName.Controls)
{
if (item.ItemType != ListItemType.Footer) continue;
var lblMyLabel = ((Label)item.FindControl("lblMyLabel"));
lblMyLabel.Text = "I found it!!!";
}

What's the best way to show multiple checkboxes for multiple records in ASP.NET

The situation is as follows:
I have a database with many RSS Categories, that in turn have many RSS Feeds. I want to display them in the following fashion:
RSS Category 1
[ ] Rss Feed 1
[ ] Rss Feed 2
[ ] Rss Feed 3
RSS Category 2
[ ] Rss Feed 1
[ ] Rss Feed 2
[ ] Rss Feed 3
Where [ ] represents a checkbox.
So each RSS Feed is pulled out of the database depending on the id of the parent RSS category. I cannot use CheckBoxList as each checkbox must be contained inside an unordered list list item. I need the markup to be semantically correct and cant use the Control Adapters.
I initially imagined two nested repeaters, the outside one databound to a list of RSS Categories from the database which displays the Category header and contains a hidden control with the Category ID, then an inner Repeater with the RSS Feeds for that category.
How do I access the Category id from the hidden field control in the parent repeater so I can look up the correct RSS Feeds?
I think you might be looking for something like this:
ASPX:
<asp:Repeater ID="rptOuter" runat="server" OnItemDataBound="rptOuter_ItemDataBound">
<HeaderTemplate>
<ul style="list-style-type: none">
</HeaderTemplate>
<ItemTemplate>
<li id='<%# Eval("Id") %>'>
<%# Eval("Category") %>
<asp:Repeater ID="rptInner" runat="server">
<HeaderTemplate>
<ul style="list-style-type: none">
</HeaderTemplate>
<ItemTemplate>
<li>
<asp:CheckBox ID="chkFeed" runat="server" Text='<%# Eval("Feed") %>' />
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
Code Behind:
protected void Page_Load(object sender, EventArgs e)
{
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT id, category FROM rsscategory_tbl", conn);
SqlDataReader rdr = cmd.ExecuteReader();
this.rptOuter.DataSource = rdr;
this.rptOuter.DataBind();
rdr.Close();
}
}
protected void rptOuter_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
System.Data.Common.DbDataRecord rd = (System.Data.Common.DbDataRecord)e.Item.DataItem;
SqlCommand cmd = new SqlCommand("SELECT feed FROM rssfeed_tbl WHERE categoryid = " + rd.GetInt32(rd.GetOrdinal("id")), conn);
Repeater rptInner = (Repeater)e.Item.FindControl("rptInner");
SqlDataReader rdr = cmd.ExecuteReader();
rptInner.DataSource = rdr;
rptInner.DataBind();
rdr.Close();
}
}
}
If you can't use a CheckBoxList, you'll have to handle the values manually.
You can manually .Controls.Add(new LiteralControl("</li><li>")) between them, but that's a bit on the tacky side.
You could use a DataGrid with a TemplateColumn to hack your way into it, but that's not elegant.
Why does this need to be in a list? Doesn't the CheckBoxList provide the functionality you require?
Also, try myCheckBox.Parent.Controls.FindControl("MyHiddenField").Value .
How do I access the Category id from the hidden field control in the parent repeater so I can look up the correct RSS Feeds?
I have an application where I need to dynamically create a whole variety of different controls. It works fine for multiple checkboxes (or anything else for that matter).
First, on your ASPX page, place the "PlaceHolder" control:
<asp:PlaceHolder runat="server" id="CtrlCanvas" />
Now, in your code behind, create your controls dynamically:
Label aLbl = new Label {Text = "Prompt: ", ID = ("WSLabel" + counter++)};
CtrlCanvas.Controls.Add(aLbl);
That was a label, here is a TextBox:
TextBox aBox = new TextBox {ID = "XTest1", Columns = 5, Text = " ", Width = 50};
CtrlCanvas.Controls.Add(aBox);
aBox.Focus();
Here is a radio box list:
RadioButtonList WRRadio = new RadioButtonList { ID = "XTestRadioList1" };
WRRadio.Items.Add("Walking ");
WRRadio.Items.Add("Running");
WRRadio.SelectedIndex = WalkRun;
WRRadio.RepeatColumns = 2;
CtrlCanvas.Controls.Add(WRRadio);
That is all there is to creating the control. To get the values, you'll need to have a naming convention that allows you to identify the prefix that ASP.NET puts on your controls. I use "XTest". Here is an example:
foreach (string aStr in Form.AllKeys)
{
int position = aStr.IndexOf("XTest"); // XTest is used in my controls
if (position > 0)
{
// Get the *prefix* added by ASP.NET
CtlPrefix = aStr.Substring(0, position);
break;
}
}
Now to get the value stored in a specific control it is easy:
string result = Form.Get(CtlPrefix + "XTest1")
For radio boxes, at least, the Get returns the selected index. I imagine that you'll name each check box separately so you can just check for 0 or 1.
Hope this helps!
I need the markup to be semantically correct and cant use the Control Adapters.
Are you referring to these adapters? If not, you should take a look. You don't have to use the entire set; Edit your .browser file to specify only the CheckBoxListAdapter. It should do exactly what you need. This way you can simply take a Repeater or ListView control and databind it to the list of categories, then put a CheckBoxList inside that.

Resources