Calculate in dynamic created textbox - c#

How can I add values in my dynamically created texbox in another textbox ? For example I have 6 textbox named from TextBox0 to TextBox6 and I want to add the values in TextBox0 to TextBox5 then set that values in TextBox6. How can I do that?
This is my code for create dynamic textbox:
static int column = 0;
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
if (column > 0)
{
do
{
TextBox tb = new TextBox();
tb.Text = "";
tb.Name = "TextBox" + (i + column * 6);
TextBox t = (TextBox)Controls["TextBox" + i.ToString()];
Point p = new Point(15 + (column * 125), 5 + (i * 25));
tb.Location = p;
this.Controls.Add(tb);
i++;
} while (i <= 5);
}
else
{
do
{
TextBox tb = new TextBox();
tb.Text = "";
tb.Name = "TextBox" + i;
TextBox t = (TextBox)Controls["TextBox" + i.ToString()];
Point p = new Point(15, 5 + (i * 25));
tb.Location = p;
this.Controls.Add(tb);
i++;
} while (i <= 5);
}
column++;
}

private const string _textBoxName = "TextBox";
The method count textboxes sum by given range of text box ids. Be aware this will throw exception if the text box texts / name id are not intgeres or
private int Count(int from, int to)
{
int GetIdFromTextBox(TextBox textBox) => int.Parse(new string(textBox.Name.Skip(_textBoxName.Length).ToArray()));
var textBoxes = Controls.OfType<TextBox>().ToList();
var textBoxesWithIds = textBoxes.Select(textBox => (textBox: textBox, id: GetIdFromTextBox(textBox))).ToList();
var sum = textBoxesWithIds.Where(x => x.id >= from && x.id <= to).Sum(x => int.Parse(x.textBox.Text));
return sum;
}

Related

How I get id and total value of dynamically created text boxes?

I create text boxes dynamically and use to store the data. How do I get the text boxes id and how to get total value from all text boxes?
I used this code for creating dynamic text boxes:
for (int B = 0; B < 4; B++)
{
TextBox tb = new TextBox();
int i = TextBoxes.Count + 1;
tb.Location = new Point(0, i * 28);
tb.Width = 80;
tb.Name = "ID" + i;
tb.Text = i.ToString();
TextBoxes.Add(tb);
panel1.Controls.Add(tb);
}
you can try this if you are sure that all values will only hold numbers
var allTexboxes = this.Controls.OfType<TextBox>();
var sumOfAllTextBoxes = allTexboxes.Sum(x => Convert.ToInt32(x.Text));
if not
var allTexboxes = this.Controls.OfType<TextBox>();
var sum = 0;
foreach (var allTexbox in allTexboxes)
{
if (int.TryParse(allTexbox.Text, out var i))
{
sum = sum + i;
}
}

Add rows to TableLayoutPanel at a given Index

I have TableLayoutPanel and adding rows dynamically. How can I insert the rows with controls at a specific index?
private void AddRowstoTableLayout()
{
for (int cnt = 0; cnt < 5; cnt++)
{
RowStyle newRowStyle = new RowStyle();
newRowStyle.Height = 50;
newRowStyle.SizeType = SizeType.Absolute;
Label lbl1 = new Label();
lbl1.Text = "label-" + (cnt + 1);
TextBox t1 = new TextBox();
t1.Text = "text-" + (cnt + 1);
Label lblMove = new Label();
lblMove.Text = "Move-" + (cnt + 1);
lblMove.MouseDown += new MouseEventHandler(dy_MouseDown);
tableLayoutPanel1.RowStyles.Insert(0, newRowStyle);
this.tableLayoutPanel1.Controls.Add(lbl1, 0, cnt); //correct
this.tableLayoutPanel1.Controls.Add(t1, 1, cnt); //correct
this.tableLayoutPanel1.Controls.Add(lblMove, 2, cnt); //correct
tableLayoutPanel1.RowCount += 1;
}
}
I tried
tableLayoutPanel1.RowStyles.Insert(0, newRowStyle);
but no luck
There is no such function out of the box.
The way is to add a row to your TableLayoutPanel. Then move all controls that are positioned in rows greater equal to your desired row index in a rowindex higher than their current position.
Here how you can do that:
void InsertTableLayoutPanelRow(int index)
{
RowStyle newRowStyle = new RowStyle();
newRowStyle.Height = 50;
newRowStyle.SizeType = SizeType.Absolute;
tableLayoutPanel1.RowStyles.Insert(index, newRowStyle);
tableLayoutPanel1.RowCount++;
foreach (Control control in tableLayoutPanel1.Controls)
{
if (tableLayoutPanel1.GetRow(control) >= index)
{
tableLayoutPanel1.SetRow(control, tableLayoutPanel1.GetRow(control) + 1);
}
}
}

How to interact with variables (just created in the program) that are in another method?

In the first method I'm creating a matrix of textboxes and in another (Button_click) method. I need to take the values of textboxes from the Button_Click method and then do something with them. I don't know how interact with just created values(the names are also new). But I know that I can't use t[j].
private void vsematrici_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
int selectedIndex = vsematrici.SelectedIndex+2;
StackPanel[] v = new StackPanel[selectedIndex];
for (int i = 0; i < selectedIndex; i++)
{
v[i] = new StackPanel();
v[i].Name = "matrixpanel" + i;
v[i].Orientation = Orientation.Horizontal;
TextBox[] t = new TextBox[selectedIndex];
for (int j = 0; j < selectedIndex; j++)
{
t[j] = new TextBox();
t[j].Name = "a" + (i + 1) + (j + 1);
t[j].Text = "a" + (i + 1) + (j + 1);
v[i].Children.Add(t[j]);
Thickness m = t[j].Margin;
m.Left = 1;
m.Bottom = 1;
t[j].Margin = m;
InputScope scope = new InputScope();
InputScopeName name = new InputScopeName();
name.NameValue = InputScopeNameValue.TelephoneNumber;
scope.Names.Add(name);
t[j].InputScope = scope;
}
mainpanel.Children.Add(v[i]);
}
Button button1 = new Button();
button1.Content = "Найти определитель";
button1.Click += Button_Click;
mainpanel.Children.Add(button1);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// Double sa11v = Convert.ToDouble(t[j].Text);
}
Sorry for my English, I'm from Russia :)
you could create a member variable that is used outside the event in which you have created TextBox Array-
TextBox[] _t = null;
private void vsematrici_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
int selectedIndex = vsematrici.SelectedIndex + 2;
StackPanel[] v = new StackPanel[selectedIndex];
for (int i = 0; i < selectedIndex; i++)
{
v[i] = new StackPanel();
v[i].Name = "matrixpanel" + i;
v[i].Orientation = Orientation.Horizontal;
_t = new TextBox[selectedIndex];
for (int j = 0; j < selectedIndex; j++)
{
_t[j] = new TextBox();
_t[j].Name = "a" + (i + 1) + (j + 1);
_t[j].Text = "a" + (i + 1) + (j + 1);
v[i].Children.Add(_t[j]);
Thickness m = t[j].Margin;
m.Left = 1;
m.Bottom = 1;
_t[j].Margin = m;
InputScope scope = new InputScope();
InputScopeName name = new InputScopeName();
name.NameValue = InputScopeNameValue.TelephoneNumber;
scope.Names.Add(name);
_t[j].InputScope = scope;
}
mainpanel.Children.Add(v[i]);
}
Button button1 = new Button();
button1.Content = "Найти определитель";
button1.Click += Button_Click;
mainpanel.Children.Add(button1);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (_t != null)
{
//Do your work here
// Double sa11v = Convert.ToDouble(t[j].Text);
}
}
but for a broader aspect, you can use dictionary,
Dictionary<string, TextBox> _dicTextBoxes;
private void vsematrici_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
int selectedIndex = vsematrici.SelectedIndex + 2;
StackPanel[] v = new StackPanel[selectedIndex];
for (int i = 0; i < selectedIndex; i++)
{
v[i] = new StackPanel();
v[i].Name = "matrixpanel" + i;
v[i].Orientation = Orientation.Horizontal;
_dicTextBoxes = new Dictionary<string, TextBox>();
for (int j = 0; j < selectedIndex; j++)
{
TextBox txtBox = new TextBox();
txtBox = new TextBox();
txtBox.Name = "a" + (i + 1) + (j + 1);
txtBox.Text = "a" + (i + 1) + (j + 1);
v[i].Children.Add(txtBox);
Thickness m = txtBox.Margin;
m.Left = 1;
m.Bottom = 1;
txtBox.Margin = m;
InputScope scope = new InputScope();
InputScopeName name = new InputScopeName();
name.NameValue = InputScopeNameValue.TelephoneNumber;
scope.Names.Add(name);
txtBox.InputScope = scope;
_dicTextBoxes.Add(txtBox.Name, txtBox);
}
mainpanel.Children.Add(v[i]);
}
Button button1 = new Button();
button1.Content = "Найти определитель";
button1.Click += Button_Click;
mainpanel.Children.Add(button1);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (_dicTextBoxes != null)
{
// a23 is the name of textbox, 'a' is prefixe, '2' is the 2nd stackpanel you have added
// '3' is the 3rd textbox you have added in stackpanel
if (_dicTextBoxes.ContainsKey("a23"))
{
//Do your work here
Double sa11v = Convert.ToDouble(_dicTextBoxes["a23"].Text);
}
}
}
Loop through the Children of mainpanel and check each control if it is a TextBox. Something like:
foreach (UIElement ctrl in mainpanel.Children)
{
if (ctrl.GetType() == typeof(TextBox))
{
TextBox oneOfYourTextBoxes = ((TextBox)ctrl);
// do your thing
}
}
You cannot change an arrays size after you created it. Hence your size is known only at runtime after firing your event you cannot set its size within the declaration.
class MyClass
{
Textbox[] myTextBoxes;
private void vsematrici_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// ...
myTextBoxes = new TextBoxes[selectedIndex];
}
private void Button_Click(object sender, RoutedEventArgs e)
{
int myIndex = // your selected item here
if (this.myTextBoxes != null && myIndex < this.myTextBoxes.Length)
{
Console.WriteLine(this.myTextBoxes[myIndex].Text);
}
}
}
This will also work:
button1.Click += (sender, args) => DoSomethingToTextboxes(_t);

I can't add more than 2 controls to canvas

I am trying to add controls at run-time for a Windows Phone app but I can't add more than 2 controls to the canvas. I have a textbox in mainscreen, and the user will enter a number which will yield that many textboxes. This code works for 0, 1, or 2 textboxes, but cannot add more than 2:
`int seriuzunlugu;
seriuzunlugu=Convert.ToInt32(SeriUzunluguTxt.Text);
int Xtop, Xleft, Ytop, Yleft;
Xtop = 10;
Xleft = 70;
Ytop = 10;
Yleft = 250;
for (int i = 0; i <seriuzunlugu ; i++)
{
//Xi değeri
TextBox Xi = new TextBox();
Xi.Name = "X" + i.ToString();
Xi.Width = 5;
Xi.Height = 5;
canvas.Children.Add(Xi);
Canvas.SetLeft(Xi,Xleft);
Canvas.SetTop(Xi,Xtop);
Xtop = +60;
//Yi değeri
TextBox Yi = new TextBox();
Yi.Name = "Y" + i.ToString();
Yi.Width = 5;
Yi.Height = 5;
canvas.Children.Add(Yi);
Canvas.SetLeft(Yi, Yleft);
Canvas.SetTop(Yi, Ytop);
Ytop = +60;
}
//X değeri
TextBox x = new TextBox();
x.Name = "xdegeri";
x.Width = 50;
x.Height = 10;
x.Text = canvas.Children.Count.ToString();
canvas.Children.Add(x);
Canvas.SetTop(x, Xtop + 50);
Canvas.SetLeft(x, Xleft);`

How to copy values from textbox into array of labels?

OK Here's what I did and the values which were set vertical are copied in the labels but horizontal. And only one column/row.
public partial class Form1 : Form
{
private Label l;
private Button bStart;
private TextBox txtVnes;
private Label[] pole;
public Form1()
{
InitializeComponent();
bStart = new Button();
bStart.Location = new Point(240, 165);
bStart.Width = 75;
bStart.Height = 25;
bStart.Text = "START";
txtVnes = new TextBox();
txtVnes.Location = new Point(240, 10);
txtVnes.Width = 160;
txtVnes.Height = 130;
txtVnes.Multiline = true;
int a = 0;
pole = new Label[42];
for (int i = 1; i <= 6; i++)
{
for (int j = 1; j <= 7; j++)
{
l = new Label();
l.Name = "label" + i.ToString() + j.ToString();
l.Text = "Z";
l.Width = 20;
l.Height = 20;
l.TextAlign = ContentAlignment.MiddleCenter;
l.Parent = this;
l.BackColor = Color.FromArgb(100, 149, 237);
l.Location = new Point(10 + (j - 1) * 25, 15 + (i - 1) * 25);
pole[a] = l;
this.Controls.Add(l);
a++;
}
}
this.Controls.Add(bStart);
this.Controls.Add(txtVnes);
bStart.Click += new EventHandler(bStart_Click);
}
private void bStart_Click(object sender, EventArgs e)
{
Regex regex = new Regex(#"^(\s)*(\d ){6}\d(\s)*$");
bool isValid = true;
string[] ts = txtVnes.Text.Split(new string[] { "\r\n" },
StringSplitOptions.RemoveEmptyEntries);
if (ts == null || ts.Length < 1 || ts.Length > 6)
{
MessageBox.Show("Not valid");
}
else
{
foreach (string t in ts)
{
if (regex.IsMatch(t) == false)
{
MessageBox.Show("Not valid");
break;
}
}
}
if (isValid)
{
for (int i = 0; i < 6; i++)
{
if (i < ts.Length && regex.IsMatch(ts[i]))
{
pole[i].Text = ts[i];
}
else
{
pole[i].Text = "not valid";
}
}
}
}
Here's a photo
So here is the problem: When I click on the button bStart only one value is copied and replaced in one labe from the array of labels.
This should work like this: After the user clicks on the button bStart, all values from the textbox txtVnes should be copied in each label in the array of labels. All the labels have text "Z", and after click on the button they should be changed with the values in the textbox txtVnes. As you can see i used l.Text = txtVnes.Text; to copy the values, but it doesn't work. I appreciate if you can help me, thank you!
You are always setting the text of the same label l. Since your labels are in the array pole, you should set the text to consecutive pole indices.
I you want all the valid texts at the beginning:
string[] ts = txtVnes.Text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
int k = 0;
for (int i = 0; i < ts.Length && k < 6; i++) {
if (IsValid(ts[i])) { // Where IsValid is a method containing your validation logic.
pole[k++].Text = ts[i];
}
}
// Fill remaining labels
for (int i = k; i < 6; i++) {
pole[i].Text = "not valid";
}
Or, if you want vaild and invalid texts mixed:
string[] ts = txtVnes.Text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < 6; i++) {
if (i < ts.Length && IsValid(ts[i])) { // Where IsValid is a method containing your validation logic.
pole[i].Text = ts[i];
} else {
pole[i].Text = "not valid";
}
}
Note that array indices begin at 0, not at 1.
EDIT #2:
The IsValid method would look like this:
private static Regex regex = new Regex(#"^(\s)*(\d ){6}\d(\s)*$");
private static bool IsValid(string s)
{
return regex.IsMatch(s);
}
To answer your question in the comment: Yes, my examples above have to be placed in bStart_Click.
And there is also another error in your form constructor. this.Controls.Add(l); should be placed inside the inner for-loop, just after pole[a] = l;, otherwise only one label will be visible on your form.
Finally after having implemented and anlyzed your code, I came to the conclusion that you want to be able to enter text in the following format into the textbox and then place the digits into corresponding labels:
1 2 3 4 5 6 7
2 3 4 6 7 8 0
0 1 2 6 6 6 7
1 2 3 4 5 6 7
2 3 4 6 7 8 0
0 1 2 6 6 6 7
The complete code should look like this:
public partial class Form1 : Form
{
private Button bStart;
private TextBox txtVnes;
private Label[] pole;
public Form1()
{
InitializeComponent();
bStart = new Button();
bStart.Location = new Point(240, 165);
bStart.Width = 75;
bStart.Height = 25;
bStart.Text = "START";
bStart.Click += new EventHandler(bStart_Click);
this.Controls.Add(bStart);
txtVnes = new TextBox();
txtVnes.Location = new Point(240, 10);
txtVnes.Width = 160;
txtVnes.Height = 130;
txtVnes.Multiline = true;
this.Controls.Add(txtVnes);
int a = 0;
pole = new Label[42];
for (int i = 1; i <= 6; i++) {
for (int j = 1; j <= 7; j++) {
var l = new Label();
l.Name = "label" + i.ToString() + j.ToString();
l.Text = "Z";
l.Width = 20;
l.Height = 20;
l.TextAlign = ContentAlignment.MiddleCenter;
l.Parent = this;
l.BackColor = Color.FromArgb(100, 149, 237);
l.Location = new Point(10 + (j - 1) * 25, 15 + (i - 1) * 25);
pole[a] = l;
this.Controls.Add(l);
a++;
}
}
}
private void bStart_Click(object sender, EventArgs e)
{
string[] ts = txtVnes.Text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
int row = 0;
for (int i = 0; i < ts.Length && row < 6; i++) {
if (LineIsValid(ts[i])) {
for (int col = 0; col < 7; col++) {
pole[row * 7 + col].Text = ts[i][2 * col].ToString();
}
row++;
}
}
// Fill remaining labels
for (; row < 6; row++) {
for (int col = 0; col < 7; col++) {
pole[row * 7 + col].Text = "Z";
}
}
}
private static Regex regex = new Regex(#"^(\s)*(\d ){6}\d(\s)*$");
private static bool LineIsValid(string line)
{
return regex.IsMatch(line);
}
}
Two nested loops are required in bStart_Click as well. One for the rows and one for the columns.

Categories

Resources