Textbox1.text is user can enter html page name, so that its is appending to panel through literal.(loading html page to pannel).
string val = TextBox1.Text;
string location = Server.MapPath(".");
string path = location + "\\HTML\\" + val + ".html"; // HTML IS FOLDER NAME IN MY PROJECT
string readText = System.IO.File.ReadAllText(path);
Panel1.Controls.Clear();
Literal lit = new Literal();
lit.Text = readText;
Panel1.Controls.Add(lit);
Actually in Html page few controls which are in format of input (<input style="position: relative;" id="T0" onmouseup="mUp(this.id)" class="ui-draggable" onmousedown="mDown(this.id)" value="" type="text">)
I have to find those id's and text to save in database.
how to find the controls in panel now?
Give an ID to the control when you add it.
Literal lit = new Literal();
lit.Text = readText;
lit.ID = "myLiteral";
Panel1.Controls.Add(lit);
Then you can get it back as follows:
Literal lit = (Literal)Panel1.FincControl("myLiteral");
Remember that dynamically added controls must be created added again on every PostBack that follows as long as you want to have access to them.
Give your Literal an ID and then you can access it via FindControl...
Literal myLiteral = Panel1.FindControl("litId") as Literal;
if (myLiteral != null)
{
// ... do something
}
EDIT: (Missed the last part of your question)
You need to use ParseControl([string value]) on the HTML content which returns a control and then add that control (containing all child controls) to the Panel. Then you can use FindControl to locate child controls. For this method, the controls must be .NET controls (ie.
Since you did not give id to the control, u can find them by Panel1.Controls[index], since it is the first control added u can access at Panel1.Controls[0]
Related
I'm creating a new tab on a TabControl, and inside of that tab contains a RichTextBox semi-dynamically named by setting the name Variable like so:
chatWindow.Name = name + "ChatArea";
"name" being the name of the chat channel the user has joined.
ex: name = Test, RTB Name would be: TestChatArea.
Is there an easy way to access that control via code, or am I going about this the completely wrong way?
To programmatically retrieve the TabPage where your RichTextBox control is contained you should search all the tabPage inside your TabControl and check if any RichTextBox in that page has the Name that you are searching for
foreach(TabPage tp in yourTablControl.TabPages)
{
RichTextBox rtb = tp.Controls.OfType<RichTextBox().FirstOrDefault(x => x.Name == name + "ChatArea");
if(rtb != null)
{
// rtb is your control, do your stuff in a sub
// passing the found control and break the loop
DoYouStuffWithRichTextBox(rtb)
break;
}
}
Of course you need to have a way to identify the variable part of this code. Meaning the variable name should have been set before entering this loop with the actual value that you are searching for.
This code will be simpler if we can assume that you have just one RichTextBox for each TabPage. In this case, when dinamically creating the TabPage and its RichTextBox you could set the Name property of the TabPage to your chat area and use that as a way to identify your control
TabPage tp = yourTablControl.TabPages["chatAreaName"];
RichTextBox rtb = tp.Controls.OfType<RichTextBox().FirstOrDefault();
if(rtb != null)
{
....
On the sever side, I've created, a literal with text set to an input type file element with runat = 'server' property, mode set to passThrough and append it to a div. Both the literal and input element have it's own unique id. My issue is trying to get that input element from the div tag. I'm able to get the literal programmatically, but the literal doesn't contain any controls and text value has the input element I need. I tried looking for the input element o it's own and keep getting null. I've inspected the page and I see the input element with runat='server'and it's and yet I can't get it. I need to be able to get this input element in order to upload it's file.
This is what I've tried so far:
Client-Side:
<div runat="server" id="docRequeridosMainDiv" style="display: table;
width: 60%; text-align: right">
<%-- Control set on server side --%>
</div>
Server-Side: (Testing this on pageload event)
//Attach inivisible input type file
uploadLit.Text += string.Format(#"<div><input type='file' id='{0}File' runat = 'server' style='display: none;'
onchange='" + docsRequeridos.ElementAt(i).Nombre + #"FileSelected()' /></div>", lbl.Text);
uploadLit.ID = lbl.Text + "FileLit";
docRequeridosMainDiv.Controls.Add(uploadLit);
//var lit = (Literal)docRequeridosMainDiv.FindControl(uploadLit.ID);
var lit = (HtmlGenericControl)docRequeridosMainDiv.FindControl(lbl.Text +"File");
Ignore the event attached to input, that works.
I've debugged the commented lit and on the controls collection has 0 but the text has the input. The second lit is returns a null value.
Tried getting it with the same Findcontrol line on a click event and still same result. Literal with no controls.
Just in case you're wondering why the input is display:none cause I'm doing a custom file upload, but that's not important cause every other functionality works, the only on that doesn't work is this one.
FindControl() will find only server controls. Adding html control (with runat="server" as string) into a Literal will not make those controls servier-side. But you can use HtmlInputFile to achieve the same, like this:
var fileInput = new HtmlFileInput
{
ID = lbl.Text + "File"
};
fileInput.Attributes["onchange"] = docsRequeridos.ElementAt(i).Nombre + "FileSelected()";
fileInput.Attributes["style"] = "display:none";
docRequeridosMainDiv.Controls.Add(fileInput);
Now, you can find this control like:
var foundFileInput = docRequeridosMainDiv.FindControl(lbl.Text +"File") as HtmlFileInput;
If you want to wrap this file input with div, you need to make another HtmlGenericControl and add that fileInput to that; like this:
var myDiv = new HtmlGenericControl("div")
{
ID = "FileUploadContainer"
};
myDiv.Controls.Add(fileInput);
docRequeridosMainDiv.Controls.Add(myDiv); // Add myDiv instead of fileInput
This will generate exactly the html you wanted, but just programmatically (not with Literal string), and controls are now server-side.
I'm having an issue with programmatically adding a RegularExpressionValidator to any Container control (Panel, Placeholder, etc.). Here is my code:
// Get the path of the file on the server
string page = Page.Request.FilePath;
int managementCompanyId = Convert.ToInt32(Session["ManagementCompanyId_AddResident"].ToString().Trim());
// Get field validation details
Collection<ExportFieldValidation> details = ValidationBL.GetValidationDetails(managementCompanyId, page);
ContentPlaceHolder body = Page.Form.FindControl("ContentBody") as ContentPlaceHolder;
foreach (ExportFieldValidation detailItem in details)
{
// Check if the control exists on the page
TextBox control = body.FindControl(detailItem.FieldToValidate) as TextBox;
if (control != null)
{
RegularExpressionValidator regex = new RegularExpressionValidator()
{
ControlToValidate = control.UniqueID.ToString(),
ID = detailItem.ValidatorFieldName,
ValidationExpression = detailItem.RegularExpression,
Page = this,
SetFocusOnError = true,
Text = detailItem.ErrorMessage,
Enabled = true,
EnableViewState = true,
CssClass = "Error"
};
Panel validationPanel = body.FindControl("PanelAddResident") as Panel;
validationPanel.Controls.Add(regex);
}
}
When I go to the page I get the error Unable to find control id 'myControl' referenced by the 'ControlToValidate' property of 'RegularExpressionValidatorResidentId', where my control is the control.UniqueID.ToString() from above, which we store in the database and is for sure correct, as I've double-, triple- and quadruple-checked the value.
However, if I replace validationPanel.Controls.Add(regex); with Page.Form.Controls.Add(regex); everything works perfectly.
Is there a way to add my validator to the container? I'm sure I'm just doing something wrong or missing a step in the middle somewhere. Any help would be greatly appreciated.
This part is wrong:
ControlToValidate = control.UniqueID.ToString()
You need to use this:
ControlToValidate = control.ID;
You must provide an ID for control before.
UniqueID is the name the component will have in the client but Validator Controls use the server side control name to do this.
i have a custom control that renders a number of literalcontrols in the createchildcontrols method. as below (there are other lines of literalcontrols being added that i have not uncluded here)
this.Controls.Add(new LiteralControl(string.Format("<input type=\"text\" style=\"display:none\" value=\"{0}\" id=\"{1}\" name=\"{1}\" />", MediaId.ToString(), this.UniqueID)));
i am then trying to validate this textbox via adding the [ValidationProperty("myprop")] at the top of the class.
basically i need to validate against the value entered into the textbox. the myprop property is as follows
public string myprop
{
get
{
Control ctrl = this.FindControl(this.UniqueID);
string txt = ((TextBox)ctrl).Text;
try
{
MediaId = Convert.ToInt32(txt);
}
catch { MediaId = 0; }
return txt;
}
}
unfortunately the findcontrol does not find the textbox at all, i presume because as far as .net is concerned its a literalcontrol, not a textbox at all
now for sure i could change the createchildcontrols to do this
TextBox tb = new TextBox();
tb.Text = this.MediaId.ToString();
tb.ID = this.UniqueID;
this.Controls.Add(tb);
but because of other limitations of what i am doing i would have to change a great deal more stuff in other places..
is there anyway of getting findcontrol to find the textbox rendered inside the literal, or another method?
thanks
nat
unfortunately the findcontrol does not
find the textbox at all, i presume
because as far as .net is concerned
its a literalcontrol, not a textbox at
all
That is correct. You have to use some other control like a textbox.
i'm having issues retreiving the values out of a dynamically created dropdownlist. all controls are created in the Page_Init section. the listitems are added at that time as well from an array of listitems. (the controls are named the same so should be accessable to the viewstate for appropriate setting.)
here is the function that attempts to retrieve the values:
protected void Eng98AssignmentComplete_Click(object sender, EventArgs e)
{
String myID = "0";
Page page = Page;
Control postbackControlInstance = null;
// handle the Button control postbacks
for (int i = 0; i < page.Request.Form.Keys.Count; i++)
{
postbackControlInstance = page.FindControl(page.Request.Form.Keys[i]);
//Response.Write(page.Request.Form.Keys[i].ToString());
if (postbackControlInstance is System.Web.UI.WebControls.Button)
{
myID = Convert.ToString(
postbackControlInstance.ID.Replace("button_", ""));
}
}
String txtholder = "ctl00$ContentPlaceHolder$Eng098Instructors_" + myID;
Response.Write("MYID: " + myID + "<br/>");
DropDownList ddInstructorCheck = (DropDownList)Page.FindControl(txtholder);
Response.Write("Instructor Selected: "
+ ddInstructorCheck.SelectedValue + "<br/>");
}
here is the output I get, no matter which instructor was selected.....
MYID: 1_1
Instructor Selected: 0
ctl00$ContentPlaceHolder$Eng098Instructors_1_1
the name of the control is correct (verified via view source)....
ideas?
You're going to a lot of work to build this fancy string:
ctl00$ContentPlaceHolder$Eng098Instructors_1_1
That is the client ID of your control, not the server id. This code is running on the server side, and so you need the server id. To get that control using the server id, you need to do this:
ContentPlaceHolder.FindControl("Eng08Instructors_1_1");
Notice I didn't look in the page, because your content place holder created a new naming container.
Also, the way your loop is set up the myID variable will always end up holding the last button in the Keys collection. Why even bother with the loop?
Based on your comments, a better way to find the id of the dropdownlist is like this:
string id = ((Control)sender).ID.Replace("button_", "Eng098Instructors_");
why not just save the control in an instance in your class so that you don't have to use FindControl?
Do you also re-create the controls during the postback? Dynamically generated/added controls must be re-created with every request, they are not automatically re-created.
Why don't you cast the sender? This should be the button that caused the postback:
string myId = "0";
Button btn = sender as Button;
if (btn != null)
myId = btn.ID
...
You need to perform something like this because the UniqueID property is the key in Request.Form.
List<Button> buttons = new List<Button>();
List<DropDownList> dropdowns = new List<DropDownList>();
foreach (Control c in Controls)
{
Button b = (c as Button);
if (b != null)
{
buttons.Add(b);
}
DropDownList d = (c as DropDownList);
if (d != null)
{
dropdowns.Add(d);
}
}
foreach (String key in Request.Form.Keys)
{
foreach (Button b in buttons)
{
if (b.UniqueID == key)
{
String id = b.ID.Replace("button_", "");
String unique_id = "ctl00$ContentPlaceHolder$Eng098Instructors_" + id;
Response.Write("MYID: " + id + "<br/>");
foreach (DropDownList d in dropdowns)
{
if (d.UniqueID == unique_id)
{
Response.Write("Instructor Selected: " + d.SelectedValue + "<br/>");
break;
}
}
}
}
}
I'm not sure why you are generating the control in code (you can still add items dynamically if you do), but the code that generates the controls would probably be a huge help here. I'm guessing you are not setting the list item value, and instead just setting the list item text. Try seeing what you get from the SelectedText field and post your control creation function.
EDIT:
In response to your comment on #Martin's post, you said "yes I recreate the controls in the Page_Init function each time the page is created (initial or postback)". Are you also setting the selected value when you create them?
You can also use controls on the page even if your data comes from a database, the controls themselves don't have to be dynamically generated.
How about this?
((Button)sender).Parent.FindControl(myid)
Edit:I misunderstood your question. But i think you should follow page lifecycle. it is common issue for dynamically created controls.
I did some research and here is some info about Dynamically Created Controls may help you...
I had 2 catches.... here's what they were.
1. I didn't clear the table I was adding to before re-creating the controls.
apparently my attention to detail was off yesterday, i'm pretty sure the ctlXX frontrunner of the control was some different number upon postback due to how I was recreating the controls.
2. I was assigning the same list to all the dropdownlist controls.
once I called the lookup upon each creation a dropdownlist control, all works well.
anyway for what it's worth....