I added 89 textboxes dynamically. I want to get the value of the textboxes to xml. I can add the textboxes just fine the problem is I cant get the values on those dynamically
added textboxes.
For example i want to get value from textBox1 to the node "F1" in XML ,from textBox2 to node "F2" in XML.
private void button1_Click(object sender, EventArgs e)
{
XmlNodeList xnList;
XmlDocument doc = new XmlDocument();
string dosyayolu = Application.StartupPath + "\\coupling.xml";
doc.Load(dosyayolu);
if (globaller.hangimenu == "TWT1")
{
xnList = doc.SelectNodes("/coup/TWT1");
}
else
{
xnList = doc.SelectNodes("/coup/TWT2");
}
for (int i = 0; i < 89; i++)
{
foreach (XmlNode xn in xnList)
{
xn["F" + (i + 1).ToString()].InnerText = "k";
// xn["F1"].InnerText = textBox1.Text;
}
}
doc.Save(dosyayolu);
}
You could use the extension ChildrenOfType<T>().
Assuming that grid is the parent of all your TextBoxes..
var textBoxes= grid.ChildrenOfType<TextBox>().ToArray();
for (int i = 0; i < 89; i++)
{
foreach (XmlNode xn in xnList)
{
xn["F" + (i + 1).ToString()].InnerText = "k";
xn["F1"].InnerText = textBoxes[ i ].Text;
}
}
i'm guessing your textboxes are of name textBox1, textBox2, .... also your xml nodes start on F1 instead of F2 so i altered the For loop a bit
for (int i = 1; i < 90; i++)
{
foreach (XmlNode xn in xnList)
{
// this if textboxes on form, yourUserControlName if it is under a usercontrol
var tb = (TextBox)this.Controls["textBox" + i];
xn["F" + i].InnerText = tb.Text;
}
}
Edited in favor of comment of Hassan Nisar
you can do it like this:
//create
StackPanel sp = new StackPanel();
for(int i=0;i<89;i++)
{
TextBox tb = new TextBox();
sp.Children.Add(tb);
}
//get
foreach(TextBox tb in sp.Children)
{
}
or you can add all the textboxs to a list,and get them from list by index
Related
I'm making a database manager program and the program creates only as much textbox
as needed (counts the columns in the table). But for some reason the program is not removing all the textboxes I want.
New textboxes should be created and old ones should be removed on every "ComboBoxSelectedIndexChange".
Here is my code snippet:
var elm = panel20.Controls.OfType<System.Windows.Forms.TextBox>();
foreach (var item in elm)
{
DeleteControlsWithTag(item.Tag.ToString());
}
button19.Enabled = true;
one_cond = string.Empty;
if (comboBox19.Text != string.Empty)
{
one_cond = comboBox19.Text.ToUpper();
if (one_cond == "ÖSSZES")
{
string allcolumn = "(";
colnames.Remove("Összes");
for (int i = 0; i < colnames.Count - 1; i++)
{
allcolumn += colnames.ElementAt(i) + ",";
}
allcolumn += colnames.Last() + ")";
button19.Enabled = false;
textBox16.Text = ManualQuery + " " + from + " " + allcolumn + " " + "VALUES" + " ";
if (3 < colnames.Count)
{
for (int i = 0; i < colnames.Count; i++)
{
System.Windows.Forms.TextBox textbox = new System.Windows.Forms.TextBox();
textbox.Name = $"textbox_{i}";
textbox.AccessibleName = $"textbox_{i}";
textbox.Tag = $"textbox_{i}";
panel20.Controls.Add(textbox);
textbox.Parent = panel20;
//"textbox_" + colnames[i] + i
if (2<i)
{
if (i == 3)
{
textbox.Location = new System.Drawing.Point(489, 49);
}
else
{
textbox.Location = new System.Drawing.Point(489 + ((i - 3) * 71), 49);
}
}
else
{
if (0 < i)
{
textbox.Location = new System.Drawing.Point(467 + (i * 71), 17);
}
else
{
textbox.Location = new System.Drawing.Point(467, 17);
}
}
textbox.Size = new System.Drawing.Size(64, 20);
}
}
else
{
for (int i = 0; i < colnames.Count; i++)
{
System.Windows.Forms.TextBox textbox = new System.Windows.Forms.TextBox();
textbox.Name = $"textbox_{i}";
textbox.AccessibleName = $"textbox_{i}";
textbox.Parent = panel20;
panel20.Controls.Add(textbox);
textbox.Tag = $"textbox_{i}";
if (0<i)
{
textbox.Location = new System.Drawing.Point(467 + (i*71), 17);
}
else
{
textbox.Location = new System.Drawing.Point(467, 17);
}
textbox.Size = new System.Drawing.Size(64, 20);
}
}
}
else
{
onecondinsert = "(" + one_cond + ")";
textBox16.Text = ManualQuery + " " + from + " " + onecondinsert + " " + "VALUES" + " ";
System.Windows.Forms.TextBox textbox = new System.Windows.Forms.TextBox();
textbox.Name = $"textbox";
textbox.AccessibleName = $"textbox";
textbox.Location = new System.Drawing.Point(464, 20);
textbox.Size = new System.Drawing.Size(100, 20);
textbox.Parent = panel20;
textbox.Tag = "textbox";
panel20.Controls.Add(textbox);
//tbox.TextChanged += tbox_TextChanged;
}
}
MessageBox.Show(elm.Count().ToString());
}
and here is some screenshot of how the problem looks like
on the first select it works
on this picture you can see the program did not delete all the text box.
longer textbox is the new one
On the third picture I selected another column (only one textbox should be visible) but the program deletes one textbox
as you can see here
After the third selection it deletes the last extra textbox too
3. try it "works"
I have tried different ways to delete from the panel20.controls
but all produced the same bug
Hope someone can help me, Thanks
Update:
I tried another method from here:
C#, deleting all the controls with the same .Tag
private List<Control> GetTaggedControls(string tag, Control parent)
{
var taggedControls = new List<Control>();
foreach (Control control in parent.Controls)
{
if (control.Tag?.ToString() == tag)
{
taggedControls.Add(control);
}
// Recursively call this method in case this is a container
taggedControls.AddRange(GetTaggedControls(tag, control));
}
return taggedControls;
}
// Deletes all controls with the specified tag
private void DeleteControlsWithTag(string tag)
{
foreach (Control control in GetTaggedControls(tag, this))
{
panel20.Controls.Remove(control);
}
}
and I tried to delete the textboxes like this:
var elm = panel20.Controls.OfType<System.Windows.Forms.TextBox>();
foreach (var item in elm)
{
DeleteControlsWithTag(item.Tag.ToString());
}
but it is still not working
Your GetTaggedControls() function is finding ANY type of control, RECURSIVELY starting at the main Form container level, that has a specific tag. So returned controls might not be from many containers, but your DeleteControlsWithTag() method tries to remove all matches only from panel20. That may or may not be a problem; it's unclear from the pictures and possibly incomplete posted code.
When you say remove the old textboxes, can we simply remove ALL existing TextBoxes, or do you really need to match tags?
From your original attempt:
var elm = panel20.Controls.OfType<System.Windows.Forms.TextBox>();
foreach (var item in elm)
{
DeleteControlsWithTag(item.Tag.ToString());
}
This is finding ALL textboxes in panel20, then trying to delete them based on matching tags with the helper function. So the tag doesn't even matter since you are finding all textboxes to begin with...
Just try removing all TextBoxes from panel20?
var elm = panel20.Controls.OfType<System.Windows.Forms.TextBox>().ToList();
elm.ForEach(tb => panel20.Controls.Remove(tb));
Okay, now I tried to tie together Idle_Mind's and LarsTech's recommendation
and finally it's working fine with "Dispose".
Thanks guys for your quick help.
here is the previous code:
var elm = panel20.Controls.OfType<System.Windows.Forms.TextBox>();
foreach (var item in elm)
{
DeleteControlsWithTag(item.Tag.ToString());
}
and here is the new one:
var elm = panel20.Controls.OfType<System.Windows.Forms.TextBox>().ToList();
elm.ForEach(tb => tb.Dispose());
I have a little problem. First of all, some info:
- On my page, I have an UpdatePanel with a button inside it.
- When you click this button, I generate a new row with dropdown lists. Each time I have to generate a table from scratch, because it resets after the click, so I update [ViewState] value and generate as many rows as clicks.
- Outside the panel, I have another button. After clicking this button, I want to collect data from drop-down lists. To do it, I have to get to these controls.
I tried to use function FindControl(), but I guess I can't - as far as I know, it does not perform a deep search. This means I have to pass as a parameter the exact container with this control. Because control is inside the table, I should get to the <td> value and I can't do that (<td> does not have ID - yes, I can add it but <td> is also dynamically created. That means I would need to get first to <td>, then to my control (guess what - <tr> is also created dynamically).
Because I can't use FindControl function, I use FindRecursiveControl function (code below) The problem is, that this function neither finds anything. Any suggestions about what might be the reason? I added this whole info in case that the reason is for example usage of UpdatePanel and page life cycle.
private Control FindControlRecursive(Control rootControl, string controlID)
{
if (rootControl.ID == controlID)
{
return rootControl;
}
foreach (Control controlToSearch in rootControl.Controls)
{
Control controlToReturn =
FindControlRecursive(controlToSearch, controlID);
if (controlToReturn != null)
{
return controlToReturn;
}
}
return null;
}
My usage of this function:
string control_id = "parametr" + i;
DropDownList dropdown = (DropDownList)FindControlRecursive(UpdatePanel1, control_id);
Script generating table in UpdatePanel after button click
protected void generuj_tabele(int il_klik)
{
il_par.Text = "Ilość parametrów: " + il_klik.ToString();
TableRow table_head = new TableRow();
table_head.Attributes.Add("class", "w3-green");
Table1.Rows.Add(table_head);
for (int j = 0; j < 5; j++)
{
TableCell cell = new TableCell();
table_head.Cells.Add(cell);
}
Table1.Rows[0].Cells[0].Text = "Parametr";
Table1.Rows[0].Cells[1].Text = "Wartość początkowa";
Table1.Rows[0].Cells[2].Text = "Inkrementacja?";
Table1.Rows[0].Cells[3].Text = "Zwiększ o:";
Table1.Rows[0].Cells[4].Text = "Zwiększ co:";
RootObject obj = (RootObject)Session["get_offer"];
for (int i = 0; i < il_klik; i++)
{
parametr = new DropDownList();
wartosc = new TextBox();
inkrementacja = new CheckBox();
inkrementacja_numer = new TextBox();
skok = new TextBox();
//inkrementacja_numer.Enabled = false;
// skok.Enabled = false;
inkrementacja_numer.Attributes.Add("Type", "number");
skok.Attributes.Add("Type", "number");
//inkrementacja.CheckedChanged += new EventHandler((s, eventarg) => checkbox_change(s, eventarg, i));
//inkrementacja.AutoPostBack = true;
//parametr.AutoPostBack = true;
TableRow row = new TableRow();
Table1.Rows.Add(row);
parametr.EnableViewState = true;
wartosc.EnableViewState = true;
inkrementacja.EnableViewState = true;
inkrementacja_numer.EnableViewState = true;
skok.EnableViewState = true;
for (int j = 0; j < 5; j++)
{
TableCell cell = new TableCell();
row.Cells.Add(cell);
}
Table1.Rows[i + 1].Cells[0].Controls.Add(parametr);
Table1.Rows[i + 1].Cells[1].Controls.Add(wartosc);
Table1.Rows[i + 1].Cells[2].Controls.Add(inkrementacja);
Table1.Rows[i + 1].Cells[3].Controls.Add(inkrementacja_numer);
Table1.Rows[i + 1].Cells[4].Controls.Add(skok);
if (i == il_klik - 1)
{
wystaw_liste(obj);
Price pr = obj.sellingMode.price;
parametr.Items.Add(pr.amount.ToString());
List<Parameter> par = obj.parameters;
foreach (Parameter p in par)
{
List<string> val = p.values;
if (val.Count() > 0)
{
foreach (string v in val)
{
parametr.Items.Add(v);
}
}
}
foreach (string p in parametry_list)
{
parametr.Items.Add(p);
}
parametry_list.Clear();
}
parametry.Add(parametr);
wartosci.Add(wartosc);
inkrementacje.Add(inkrementacja);
inkrementacje_numery.Add(inkrementacja_numer);
skoki.Add(skok);
if (i == il_klik - 1)
{
Session["v_parametr"] = parametry;
Session["v_wartosc"] = wartosci;
Session["v_inkrementacja"] = inkrementacje;
Session["v_ink_nr"] = inkrementacje_numery;
Session["v_skok"] = skoki;
}
parametr.ID = "parametr" + i;
wartosc.ID = "wartosc" + i;
inkrementacja.ID = "inkrementacja" + i;
inkrementacja_numer.ID = "inkrementacja_numer" + i;
skok.ID = "skok" + i;
}
}
When I try to check parameters of DropDownList (e.g. SelectedValue) I get error "Object reference not set to an instance of an object"
I am using a TreeView to show a folderstructure. I dynamically create nodes in the NodeMouseClick event.
But even though the child nodes are populated, they are not visible in the treeview.
However, minimizing the window and maximizing it again solves this issue. Please let me know what I am doing wrong here. Please find below the code that I am using:
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (treeView1.SelectedNode != null && e.Node.IsExpanded)
{
treeView1.BeginUpdate();
TreeNode node = e.Node;
while (node.Parent != null)
{
node = node.Parent;
}
VcDetailsEntity detailsEntity = connectedVCs.Where(c => c.VCName == node.Name).FirstOrDefault();
detailsEntity.VCBrowserPath = e.Node.Name;
FolderBrowser cosmosBrowser = new FolderBrowser();
List<FolderStreamEntity> folderStreams = folderBrowser.GetVcContentDetails(detailsEntity);
e.Node.Nodes.Clear();
foreach (var stream in folderStreams)
{
if (stream.IsDirectory)
{
TreeNode treeNode = new TreeNode();
treeNode.Name = stream.StreamName;
treeNode.Text = stream.QualifiedName;
treeNode.ToolTipText = stream.QualifiedName;
TreeNode dummyNode = new TreeNode();
treeNode.Nodes.Add((TreeNode)dummyNode.Clone());
TreeNode toUpdate = treeView1.Nodes.Find(e.Node.Name, true).FirstOrDefault();
toUpdate.Nodes.Add((TreeNode)treeNode.Clone());
}
}
treeView1.EndUpdate();
treeView1.Refresh();
}
}
I have tried the suggestions provided by Gnial0id, wpfnoop and LarsTech here below. But no luck. Temporarily I have resolved it by minimizing and maximizing the form programatically.
Well, it's hard to figure out anything from the provided code snippet because many parts are missing. Also I don't quite understand why TreeNode toUpdate = treeView1.Nodes.Find(e.Node.Name, true).FirstOrDefault(); is needed and then why you are cloning the node you just created etc. So I've prepared a sample test which is doing something similar and it does not experience the problem you are describing. Check it out and compare it to your code to find out what is wrong.
using System;
using System.Windows.Forms;
namespace Samples
{
static class Test
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form();
var treeView = new TreeView { Dock = DockStyle.Fill, Parent = form };
for (int i = 1; i <= 10; i++)
{
var parent = new TreeNode { Text = "Parent#" + i };
treeView.Nodes.Add(parent);
for (int j = 1; j <= 10; j++)
{
var child = new TreeNode { Text = "Child#" + i };
var dummy = new TreeNode();
child.Nodes.Add(dummy);
parent.Nodes.Add(child);
}
}
var random = new Random();
int addCount = 0;
treeView.NodeMouseClick += (sender, e) =>
{
if (treeView.SelectedNode == e.Node && e.Node.IsExpanded)
{
treeView.BeginUpdate();
e.Node.Nodes.Clear();
int count = random.Next(20) + 1;
for (int i = 1; i <= count; i++)
{
var child = new TreeNode { Text = "AddChild#" + (++addCount) };
var dummy = new TreeNode();
child.Nodes.Add(dummy);
e.Node.Nodes.Add(child);
}
treeView.EndUpdate();
}
};
Application.Run(form);
}
}
}
Adding below code bloc immediately after the code to add a New Node did the magic for me.
treeView1.SelectedNode = NodeToUpdate;
Here the NodeToUpdate is the node where the new child nodes are added.
How do i add a new row to an xmlfile existing id number?
I want to be able to add a new row to my xml file, but using the same id from the file. My xml files have three rows and I want to add rows until I get tired. this is what is mean;
I have an xml file.
I have loaded the xmlfile to the datagridview
File loaded to the datagridview with current data.
The user must continue with capturing new rows or unlimited rows.
After all the changes it must goes to the file.
Everything is working, reading, writing and editing the current cell from three rows and saving. I want to be able to add a new rows with these three ID's which are:
name="model"
name="year"
name="color"
If I add another row it throws an error
XML file:
<root>
<dealer name="model">
<number>Hashback</number>
</dealer>
<dealer name="year">
<year>2008</year>
</dealer>
<dealer name="color">
<color>black</color>
</dealer>
</root>
My code:
private void btnSave_Click(object sender, EventArgs e)
{
XmlDocument doc = new XmlDocument();
doc.Load(FilePath);
XmlNode root = doc.DocumentElement;
XmlNodeList CnodesList = root.SelectNodes("descendant::dealer");
string Tag = string.Empty;
int iTotalRowCount = Gridview_Output.Rows.Count - 1;
for (int i = 0; i < iTotalRowCount; i++)
{
Tag = "";
string name = Gridview_Output.Rows[i].Cells[0].Value.ToString();
if (Gridview_Output.Rows[i].Cells[1].Value.ToString().Length > 0)
{
Tag = Gridview_Output.Rows[i].Cells[1].Value.ToString();
}
if (Gridview_Output.Rows[i].Cells[2].Value.ToString().Length > 0)
{
Tag = Gridview_Output.Rows[i].Cells[2].Value.ToString();
}
if (Gridview_Output.Rows[i].Cells[3].Value.ToString().Length > 0)
{
Tag = Gridview_Output.Rows[i].Cells[3].Value.ToString();
}
XmlAttributeCollection xxxx = CnodesList[i].Attributes;
for (int x = 0; x < xxxx.Count; x++)
{
if (xxxx[x].Value.ToString().Contains(name))
{
XmlNodeList Elements = CnodesList[i].ChildNodes;
for (int z = 0; z < Elements.Count; z++)
{
if (Elements[z].Name == "number")
{
Elements[z].InnerXml = Tag;
}
if (Elements[z].Name == "year")
{
Elements[z].InnerXml = Tag;
}
if (Elements[z].Name == "color")
{
Elements[z].InnerXml = Tag;
}
}
}
}
}
doc.Save(FilePath);
}
I want to access multiple textbox name textbox1,textbox2,textbox3, etc.. by loop not by individual name. For that reason I created one function which create this var names.
public string[] nameCre(string cntrlName, int size)
{
string[] t = new string[size];
for (int i = 0; i < size; i++)
{
t[i] = cntrlName.ToString() + (i + 1);
}
return t;
}
for nameCre("Textbox",5); So this,function successfully returning me TextBox1, TextBox2 ... TextBox5.
But when I am trying to convert this string to TextBox control by
string[] t = new string[50];
t= nameCre("TextBox",5);
foreach (string s in t)
{
((TextBox) s).Text = "";
}
it giving me error :
Cannot convert type 'string' to 'System.Windows.Forms.TextBox'....
How can I accomplish this job?
var t = nameCre("TextBox",5);
foreach (var s in t)
{
var textBox = new TextBox {Name = s, Text = ""};
}
string[] t= new string[50];
t= nameCre("TextBox",5);
foreach (string s in t){
TextBox tb = (TextBox)this.Controls.FindControl(s);
tb.Text = "";
}
if you have many text boxes
foreach (Control c in this.Controls)
{
if (c.GetType().ToString() == "System.Windows.Form.Textbox")
{
c.Text = "";
}
}
Perhaps you need this -
string[] t = new string[50];
t = nameCre("TextBox", 5);
foreach (string s in t)
{
if (!string.IsNullOrEmpty(s))
{
Control ctrl = this.Controls.Find(s, true).FirstOrDefault();
if (ctrl != null && ctrl is TextBox)
{
TextBox tb = ctrl as TextBox;
tb.Text = "";
}
}
}
This post is quite old, anyway I think I can give you (or anyone else with a problem like that) an answer:
I think using an Array (or List) of TextBoxs would be the best solution for doing that:
// using an Array:
TextBox[] textBox = new TextBox[5];
textBox[0] = new TextBox() { Location = new Point(), /* etc */};
// or
textBox[0] = TextBox0; // if you already have a TextBox named TextBox0
// loop it:
for (int i = 0; i < textBox.Length; i++)
{
textBox[i].Text = "";
}
// using a List: (you need to reference System.Collections.Generic)
List<TextBox> textBox = new List<TextBox>();
textBox.Add(new TextBox() { Name = "", /* etc */});
// or
textBox.Add(TextBox0); // if you already have a TextBox named TextBox0
// loop it:
for (int i = 0; i < textBox.Count; i++)
{
textBox[i].Text = "";
}
I hope this helps :)