In pushing forward with my application (winforms) and I have found a need to have dynamically generated content to be pushed to a button that then will display that dynamic content in a messagebox.
What I am doing is reading FTP links from a file, based on a product selection, then I want to take each line and have it append a textbox and a button so that they can fill out the file name.
I have it it working where the Label, textbox and button all appear as i would expect. Now what I want is to have the button when clicked display my content that was just generated.
So the code I have right now that generates everything as expected is as follows. I just need to know how to make the button accept my ftpLabel.Text and tb.Text data. I have tried to follow the post here: How can i create dynamic button click event on dynamic button?
However, I cannot seem to make it accept any of my dynamic content.
private void productComboBox_SelectedItemChanged(object sender, EventArgs e)
{
// Read from the text file and out put the results
try
{
using (StreamReader sr = new StreamReader(selectedProduct + ".txt"))
{
string line;
int l = 0;
// build the ftp link records line by line
while ((line = sr.ReadLine()) != null)
{
Label ftpLabel = new Label();
ftpLabel.AutoSize = true;
ftpLabel.Text = line;
TextBox tb = new TextBox();
Button bt = new Button();
bt.Text = "Copy Link";
bt.Click += bt.Click;
flp.Controls.Add(ftpLabel);
flp.Controls.Add(tb);
flp.Controls.Add(bt);
l++;
}
ftpGroupBox.Controls.Add(flp);
}
}
// If the read fails then output the error message in the same section
catch (Exception ex)
{
Label ftpErrorLabel = new Label();
ftpErrorLabel.AutoSize = true;
ftpErrorLabel.ForeColor = Color.Red;
ftpErrorLabel.Text = "Error: " + ex.Message;
flp.Controls.Add(ftpErrorLabel);
ftpGroupBox.Controls.Add(flp);
}
}
void bt_Click(object sender, EventArgs e)
{
MessageBox.Show("Does this work?");
// this message displays but cannot pass my dynamicly created content to this
}
Any Advice is appreciated.
Thanks
You need a hook between the button and the corresponding label and textbox. This is probably not the correct way to do this but the easiest way it to induce a naming convention as a hook.
try
{
using (StreamReader sr = new StreamReader(selectedProduct + ".txt"))
{
string line;
int l = 0;
// build the ftp link records line by line
while ((line = sr.ReadLine()) != null)
{
Label lFTPtextext = new Label()
{
AutoSize = true,
Text = line,
Tag = l
};
Button bt = new Button()
{
Text = "Copy Link",
Tag = l
}
bt.Click += bt.Click;
TextBox tb = new TextBox()
{
Tag = l
}
flp.Controls.Add(lFTPtextext);
flp.Controls.Add(tb);
flp.Controls.Add(bt);
l++;
}
ftpGroupBox.Controls.Add(flp);
}
}
// If the read fails then output the error message in the same section
catch (Exception ex)
{
Label ftpErrorLabel = new Label();
ftpErrorLabel.AutoSize = true;
ftpErrorLabel.ForeColor = Color.Red;
ftpErrorLabel.Text = "Error: " + ex.Message;
flp.Controls.Add(ftpErrorLabel);
ftpGroupBox.Controls.Add(flp);
}
}
void bt_Click(object sender, EventArgs e)
{
string tagNumber = ((Button)sender).Tag.ToString();
var tbText= this.Controls.OfType<TextBox>()
.Where(x => x.Tag.ToString() == tagNumber)
.FirstOrDefault()
var lblText = this.Controls.OfType<Label>()
.Where(x => x.Tag.ToString() == tagNumber)
.FirstOrDefault()
MessageBox.Show(tbText.ToString() + " " + lblText.ToString());
}
Maybe not the best answer, but its how I would solve it.
Related
i am facing a trouble for few days. I had create a dynamic buttons at runtime but it will disappear on the next startup. please help. below is my coding.
private void button1_Click(object sender, EventArgs e)
{
createNewTable createTable = new createNewTable();
DialogResult dResult = createTable.ShowDialog();
string table_name = "";
if (dResult == DialogResult.OK)
{
table_name = createTable.tableName;
createTable.Dispose();
}
else if (dResult == DialogResult.Cancel)
{
createTable.Dispose();
}
if(table_name != string.Empty){
Button textbox = new Button();
textbox.Name = "btn_" + table_name;
textbox.Text = table_name;
textbox.Height = 55;
textbox.Width = 123;
textbox.MouseDown += new MouseEventHandler(textbox_MouseDown);
textbox.MouseMove += new MouseEventHandler(textbox_MouseMove);
textbox.MouseUp += new MouseEventHandler(textbox_MouseUp);
textbox.ContextMenuStrip = contextMenuStrip1;
this.Controls.Add(textbox);
}
}
i had searched some info like using XMLSerialize/application settings but it dont provided any sample for me how to add dynamic button using XMLSerialize. please help..
// add a module tab
private void add_mod_Click(object sender, EventArgs e)
{
int TabCount = 0;
int? index = searchIndex(mod_add_textbox.Text);
if (index == null)
{
RichTextBox new_rich = new RichTextBox();
new_rich.Dock = DockStyle.Fill;
TabPage NewPage = new TabPage();
TabCount += 1;
string DocumentText = mod_add_textbox.Text;
NewPage.Name = DocumentText;
NewPage.Text = DocumentText;
NewPage.Controls.Add(new_rich);
mod_tab.TabPages.Add(NewPage);
}
else
{
mod_tab.SelectedIndex = Convert.ToInt32(index);
}
}
private async void btn_file_note_Click(object sender, EventArgs e)
{
using(OpenFileDialog ofd = new OpenFileDialog() { Filter="Text Documents|*.txt", ValidateNames = true, Multiselect = false })
{
if(ofd.ShowDialog() == DialogResult.OK)
{
using (StreamReader sr = new StreamReader(ofd.FileName))
{
mod_tab.SelectedTab.Text = await sr.ReadToEndAsync();
}
}
}
}
The problem I am getting is that when I try to open a document it is opening it into the tab name rather than the rich text box inside the tab. I have changed the "mod_tab.SelectedTab" part to the name of the rich text box within the tab however I want it so whichever tab the user has selected it opens in there. Any suggestions? thank you.
You assigned the value to the Text property of selected tab. Instead you should assign the value to Text property of RichTextBox or use Load method of RichTextBox to load content. for example:
this.richTextBox1.Text = ....
Also when you create the tab and RichTextBox dynamically like you ar doing in your code, you can find it this way:
//It means: Find all RichTextBox control which are children of mod_tab.SelectedTab
//And return first of them.
var rtb = this.mod_tab.SelectedTab.Controls.OfType<RichTextBox>().FirstOrDefault();
rtb.Text = ...
Also this way:
//It means get the first child control of mod_tab.SelectedTab
//And convert it to RichTextBox.
var rtb = this.mod_tab.SelectedTab.Controls[0] as RichTextBox;
rtb.Text = ...
I have problem with ASP.NET and dynamic controls. I have three ASCX. One of them creates two textboxes and some labels. The second containing control created if first ASCX (two textboxes and some labels). In addiction, second control also have link button named “Add Next” which on click event adding another control (two textboxes and some labels). The third ASCX control contains many the second ASCX (amount depend on SQL result). I made simple image to clarify:
The orange box contains many controls. The red box adding many black boxes on click “ADD NEXT”.
For now I use session variable to save state during recreate. For one “red box” it is working, but if I add more “red boxes”, clicking every “ADD NEXT” adding new control with textboxes and labels to every “red box” instead of in this where was clicked button “ADD NEXT”. I suppose why it is happening. Because every “red box” refers to the same Session variable, but I don’t know how to fix it. I was trying during OnClick event passing unique ID and setting this ID as session variable name, but it wasn’t working as I expected.
Could you tell me, how to manage it? How looks the best way to recreate controls, how I can manage controls individually? If something is not clear, I will clarify. Always I was finding answers in stackoverflow, but this problem has outgrow me.
Best wishes.
(Sorry for my English, it doesn’t my native language)
My code.
Code for creating textboxes and some labels (Calculator.cs):
public string FLong
{
get
{
object o = ViewState["FLong"];
if (o == null)
return String.Empty;
return (string)o;
}
set { ViewState["FLong"] = value; }
}
public string FWide
{
get
{
object o = ViewState["FWide"];
if (o == null)
return String.Empty;
return (string)o;
}
set
{
ViewState["FWide"] = value;
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
CreateControlHierarchy();
ClearChildViewState();
}
protected virtual void CreateControlHierarchy()
{
Literal row = new Literal();
row.Text = "<div class='row surface'>";
Controls.Add(row);
//Add new TextBox;
Literal col = new Literal();
col.Text = "<div class='col-xs-4'>";
Controls.Add(col);
TextBox fLong = new TextBox();
fLong.ID = "fLong";
fLong.CssClass = "form-control";
//fLong.TextChanged += new EventHandler(Calculate_TextChanged);
//fLong.AutoPostBack = true;
fLong.Text = FLong;
Controls.Add(fLong);
Literal textLong = new Literal();
textLong.Text = "<span>ft. long x</span>";
Controls.Add(textLong);
RegularExpressionValidator flongValidate = new RegularExpressionValidator();
flongValidate.ControlToValidate = "fLong";
flongValidate.ErrorMessage = "Only Numbers allowed";
flongValidate.ValidationExpression = #"\d+";
flongValidate.ForeColor = System.Drawing.Color.Red;
flongValidate.Attributes["style"] = "display:block";
Controls.Add(flongValidate);
Literal colEnd = new Literal();
colEnd.Text = "</div>";
Controls.Add(colEnd);
//Add new Textbox
Literal col2 = new Literal();
col2.Text = "<div class='col-xs-4'>";
Controls.Add(col2);
TextBox fWide = new TextBox();
fWide.ID = "fWide";
fWide.CssClass = "form-control";
fWide.Text = FWide;
Controls.Add(fWide);
Literal textWide = new Literal();
textWide.Text = "<span>ft. wide</span>";
Controls.Add(textWide);
RegularExpressionValidator fwideValidate = new RegularExpressionValidator();
fwideValidate.ControlToValidate = "fWide";
fwideValidate.ErrorMessage = "Only Numbers allowed";
fwideValidate.ValidationExpression = #"\d+";
fwideValidate.ForeColor = System.Drawing.Color.Red;
fwideValidate.Attributes["style"] = "display:block";
Controls.Add(fwideValidate);
Literal col2End = new Literal();
col2End.Text = "</div>";
Controls.Add(col2End);
Literal rowEnd = new Literal();
rowEnd.Text = "</div>";
Controls.Add(rowEnd);
}
Code handling recreating (SurfaceCalculator.cs):
private int DefaultAmountControls = 1;
private string surfaceID;
public string SurfaceID
{
get { return surfaceID; }
set { surfaceID = value; }
}
public int Visibility
{
get
{
//store the object in session if not already stored
if (Session[surfaceID] == null)
Session[surfaceID] = DefaultAmountControls;
//return the object from session
return (int)Session[surfaceID];
}
set
{
if (value <= 5)
Session[surfaceID] = value;
else
Session[surfaceID] = 5;
}
}
protected void addSurface_Click(object sender, EventArgs e)
{
LinkButton b = (LinkButton)sender;
surfaceID = b.CommandArgument;
Visibility += 1;
}
protected override void OnInit(EventArgs e)
{
LinkButton addSurface = new LinkButton();
addSurface.Text = "+ Add surface";
addSurface.CommandArgument = surfaceID;
addSurface.Click += new EventHandler(addSurface_Click);
base.OnInit(e);
List<Calculator> c = Surface.Controls.OfType<Calculator>().ToList();
for (int i = 1; i <= Visibility; i++)
{
c.ElementAt(i - 1).Visible = true;
}
if (Visibility >= 5)
{
addSurface.Enabled = false;
}
Controls.Add(addSurface);
}
Code to adding many controls depending on SQL result
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
var listOfProjects = //GETTING FROM SQL
if(listOfProjects != null)
{
foreach (var proj in listOfProjects)
{
Panel placeHolder = new Panel();
placeHolder.CssClass = "surface";
placeHolder.ID = "placeHolder" + proj.DocumentID;
surfacesContainer.Controls.Add(placeHolder);
SurfaceCalculator newElement = (SurfaceCalculator)LoadControl("~/PATH_TO/CONTROL.ascx");
newElement.ID = "surfaceCalculator" + proj.DocumentID;
newElement.SurfaceID = newElement.ID;
placeHolder.Controls.Add(newElement);
}
}
}
I need your help in making text box at run time and taking values from these text boxes that user enter. i have two button and one rich_text_box , when user click on one button it creates 3 text boxes and then user click on other button it should take value from text boxes and how in rich text box .
this is code i am using to create dynamic textbox
private void create_textbox_Click(object sender, EventArgs e)
{
flowLayoutPanel1.Controls.Clear();
for(i=1;i<=3;i++)
{
TextBox text = new TextBox();
text.Name = "Text Box" + i.ToString();
//text.Text = "Text Box " + i.ToString();
flowLayoutPanel1.Controls.Add(text);
}
}
and this code i am using to take values from new created text boxes and displaying in rich text box .
private void get_value_Click(object sender, EventArgs e)
{
TextBox text = new TextBox();
for (i = 1; i <= 3; i++)
{
string value = text.Text + i.ToString();
richTextBox1.SelectedText = "\r\n" + value;
}
}
This should solve your problem:
private void get_value_Click(object sender, EventArgs e)
{
for (var c in flowLayoutPanel1.Controls)
{
var t = c as TextBox;
if (t != null)
{
richTextBox1.SelectedText = "\r\n" + t.Text;
}
}
}
In your method get_value_Click you aren't using any of the text boxes that were added to the flow layout panel. Something similar to Wolfgang Ziegler's answer should work but you will need to check the Type and Name in case you have other controls in the flow layout panel.
private void get_value_Click(object sender, EventArgs e)
{
for (i = 1; i <= 3; i++)
{
string value = this.flowLayoutPanel1.Controls["Text Box" + i].Text;
richTextBox1.SelectedText = "\r\n" + value;
}
}
This ought to do it.
I'm using PostBackUrl to post my control from a "firstwebpage.aspx" to a "secondwebpage.aspx" so that I would be able to generate some configuration files.
I do understand that I can make use of PreviousPage.FindControl("myControlId") method in my secondwebpage.aspx to get my control from "firstwebpage.aspx"and hence grab my data and it worked.
However, it seems that this method does not work on controls which I generated programmically during runtime while populating them in a table in my firstwebpage.aspx.
I also tried using this function Response.Write("--" + Request["TextBox1"].ToString() + "--");
And although this statement do printout the text in the textfield on TextBox1, it only return me the string value of textbox1. I am unable to cast it to a textbox control in the following format too
TextBox temptextBox = (TextBox)Request["TextBox1"];
My question is, how can I actually access the control which i generated programmically in "firstwebpage.aspx" on "secondwebpage.aspx"?
Please advice!
thanks alot!
//my panel and button in aspx
<asp:Panel ID="Panel2" runat="server"></asp:Panel>
<asp:Button ID="Button1" runat="server" Text="Generate Xml" PostBackUrl="~/WebForm2.aspx" onclick="Button1_Click" />
//this is my function to insert a line into the panel
public void createfilerow(string b, string path, bool x86check, bool x86enable, bool x64check, bool x64enable)
{
Label blank4 = new Label();
blank4.ID = "blank4";
blank4.Text = "";
Panel2.Controls.Add(blank4);
CheckBox c = new CheckBox();
c.Text = b.Replace(path, "");
c.Checked = true;
c.ID = "1a";
Panel2.Controls.Add(c);
CheckBox d = new CheckBox();
d.Checked = x86check;
d.Enabled = x86enable;
d.ID = "1b";
Panel2.Controls.Add(d);
CheckBox e = new CheckBox();
e.Checked = x64check;
e.Enabled = x64enable;
e.ID = "1c";
Panel2.Controls.Add(e);
}
//my virtual path in WebForm2.aspx
<%# PreviousPageType VirtualPath="~/WebForm1.aspx" %>
//my pageload handler
protected void Page_Load(object sender, EventArgs e)
{
if (PreviousPage != null)
{
CheckBox tempCheckbox = (CheckBox)Page.PreviousPage.FindControl("1a");
Button1.Text = tempCheckbox.Text;
}
}
//handler which will populate the panel upon clicking
protected void Button7_Click(object sender, EventArgs e)
{
//get foldername
if (!Directory.Exists(#"myfilepath" + TextBox2.Text))
{
//folder does not exist
//do required actions
return;
}
string[] x86files = null;
string[] x64files = null;
string[] x86filespath = null;
string[] x64filespath = null;
ArrayList common = new ArrayList();
if (Directory.Exists(#"myfilepath" + TextBox2.Text + "\\x86"))
x86files = Directory.GetFileSystemEntries("myfilepath" + TextBox2.Text + "\\x86");
if (Directory.Exists(#"myfilepath" + TextBox2.Text + "\\x64"))
x64files = Directory.GetFileSystemEntries("myfilepath" + TextBox2.Text + "\\x64");
//some codes to convert x64files and x86files to string[]
//The header for Panel, 4 column
Label FL = new Label();
FL.ID = "flavourid";
FL.Text = "Flavour";
Panel2.Controls.Add(FL);
Label filetext = new Label();
filetext.ID = "filenamelabel";
filetext.Text = "File(s)";
Panel2.Controls.Add(filetext);
Label label86 = new Label();
label86.ID = "label86";
label86.Text = "x86";
Panel2.Controls.Add(label86);
Label label64 = new Label();
label64.ID = "label64";
label64.Text = "x64";
Panel2.Controls.Add(label64);
//a for loop determine number of times codes have to be run
for (int a = 0; a < num; a++)
{
ArrayList location = new ArrayList();
if (//this iteration had to be run)
{
string path = null;
switch (//id of this iteration)
{
case id:
path = some network address
}
//check the current version of iternation
string version = //version type;
//get the platform of the version
string platform = //platform
if (curent version = certain type)
{
//do what is required.
//build a list
}
else
{
//normal routine
//do what is required
//build a list
}
//populating the panel with data from list
createflavourheader(a);
//create dynamic checkboxes according to the list
foreach(string s in list)
//createrow parameter is by version type and platform
createfilerow(readin, path, true, true, false, false);
}
}
}
form1.Controls.Add(Panel2);
}
Sorry can't show you the full code as it is long and I believe it should be confidential even though i wrote them all
Yes you can access, Below is an example
// On Page1.aspx I have a button for postback
<asp:Button ID="btnSubmit" runat="server" Text="Submit"
PostBackUrl="~/Page2.aspx" />
// Page1.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
TextBox t = new TextBox(); // created a TextBox
t.ID = "myTextBox"; // assigned an ID
form1.Controls.Add(t); // Add to form
}
Now on the second page I will get the value of TextBox as
// Page2.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (PreviousPage != null)
{
TextBox t = (TextBox) PreviousPage.FindControl("myTextBox");
string mytboxvalue = t.Text;
}
// OR
string myTextBoxValue = Request.Form["myTextBox"];
}
Updated Answer:
Panel myPanel = new Panel();
myPanel.ID = "myPanel";
TextBox t = new TextBox();
t.ID = "myTextBox";
myPanel.Controls.Add(t);
TextBox t1 = new TextBox();
t1.ID = "myTextBox1";
myPanel.Controls.Add(t1);
// Add all your child controls to your panel and at the end add your panel to your form
form1.Controls.Add(myPanel);
// on the processing page you can get the values as
protected void Page_Load(object sender, EventArgs e)
{
if (PreviousPage != null)
{
TextBox t = (TextBox) PreviousPage.FindControl("myTextBox");
string mytboxvalue = t.Text;
}
string myTextBoxValue = Request.Form["myTextBox1"];
}
I also tried using this function Response.Write("--" +
Request["TextBox1"].ToString() + "--"); And although this statement do
printout the text in the textfield on TextBox1, it only return me the
string value of textbox1. I am unable to cast it to a textbox control
in the following format too
TextBox temptextBox = (TextBox)Request["TextBox1"];
Hi lw,
I think you may try passing the type of control (e.g. 'tb') together with the content and creating a new object (e.g. TextBox) and assign it to templtexBox object.
My 20 cents.
Andy