Checkbox event handling - c#

I have a MyControl class. Inside MyClass object there are textboxes and a checkbox.
I am trying to add a checkbox event handler, but it does not work. What can be the problem?
private List<MyControls> _myControls = new List<MyControls>();
MyControls mc = new MyControls();
public void CreateFormElements(int i, StringReader sr)
{
ProductForm form2 = new ProductForm();
form2.Visible = true;
form2.Activate();
String line = "";
for (int n = 0; n < i; n++)
{
line = sr.ReadLine();
mc = new MyControls();
if (line.Length > 3)
{
String[] _line = line.Split(new char[] { '\t' });
mc.SetY(30 + n * 20);
mc.initElements(_line, n);
_myControls.Add(mc);
**mc.cb.CheckedChanged += cb_CheckedChanged;**
}
}
}
private void cb_CheckedChanged(Object sender, EventArgs e)
{
string NameSet = (sender as CheckBox).Name.Split(new char[]{'_'})[1];
MessageBox.Show(NameSet);
}
Here is the code of MyControls Class:
class MyControls
{
int x=5;
int y=30;
public CheckBox cb = new CheckBox();
public TextBox tb1 = new TextBox();
public TextBox tbSpecs = new TextBox();
public TextBox tb3 = new TextBox();
public TextBox tb4 = new TextBox();
public void initElements(String[] name, int i)
{
cb.Width = 10;
cb.Height = 10;
cb.Name = "cb_" + i.ToString();
cb.Location = new Point(x, y+5);
cb.Checked = false;
Form.ActiveForm.Controls.Add(cb);
x += 15;
tb1.Width = 50;
tb1.Height = 20;
tb1.Location = new Point(x, y);
tb1.Name = "tb1_" + i.ToString();
tb1.Text = name[0];
Form.ActiveForm.Controls.Add(tb1);
x += 60;
tbSpecs.Width = 150;
tbSpecs.Height = 20;
tbSpecs.Name = "tb2_" + i.ToString();
tbSpecs.Text = name[1];
tbSpecs.Location = new Point(x, y);
Form.ActiveForm.Controls.Add(tbSpecs);
x += 160;
tb3.Width = 40;
tb3.Height = 20;
tb3.Name = "tb3_" + i.ToString();
tb3.Text = name[2];
tb3.Location = new Point(x, y);
Form.ActiveForm.Controls.Add(tb3);
x += 50;
tb4.Width = 450;
tb4.Height = 20;
tb4.Name = "tb4_" + i.ToString();
tb4.Text = name[3];
tb4.Location = new Point(x, y);
Form.ActiveForm.Controls.Add(tb4);
x = 0;
}
public int SetX(int X)
{
x = X;
return x;
}
public int SetY(int Y)
{
y = Y;
return y;
}
}

mc.cb.CheckedChanged += new System.EventHandler(this.cb_CheckedChanged)

A few points to check in CreateFormElements(int i, StringReader sr){...}:
Is i greater than zero? If not the loop will never run and the event handler will never get attached.
Is line.Length ever greater than zero? If not you'll never get inside the if-block and the handler won't get attached.

Related

Dynamically update button

I am attempting to dynamically add a list of buttons:
private void updateClientListUI()
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(this.updateClientListUI));
}
else
{
int count = 1;
int x = 0;
int y = 0;
for (int i = 0; i < 5; i++)
{
Button btn = new Button();
btn.Text = count.ToString();
btn.Name = count.ToString();
btn.Size = new Size(35, 35);
btn.Location = new Point(150, 150 * y);
//btn.Dock = DockStyle.Fill;
y++;
count++;
Controls.Add(btn);
}
}
}
Unfortunately this does not apply any buttons to the form.
In addition I was wondering how could I append these buttons in a panel called subPanelClient
This worked for me, the issue was the position of the button, as you have to indicate it within a panel or form.
In this case i just docked them to the panel
private void updateClientListUI()
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(this.updateClientListUI));
}
else
{
//Debug.WriteLine(clientNames[0]);
int basex = subPanelClient.Location.X;
int basey = subPanelClient.Location.Y;
subPanelClient.Controls.Clear();
Debug.WriteLine(clientNames.Count);
for (int i = 0; i < clientNames.Count; i++)
{
Button b = new Button();
b.Left = basex;
b.Top = basey;
b.Size = new Size(25, 25); // <== add this line
b.Dock = DockStyle.Top;
b.ForeColor = Color.Gainsboro;
b.FlatStyle = FlatStyle.Flat;
b.FlatAppearance.BorderSize = 0;
b.Padding = new Padding(35, 0, 0, 0);
b.TextAlign = ContentAlignment.MiddleLeft;
basey += 25;
b.Name = clientNames[i];
b.Text = clientNames[i];
subPanelClient.Controls.Add(b);
buttonsAdded.Insert(i, b);
}
}
}

Increment/Decrement value from NumericUpDown

I have the following problem. I create a form with two NumericUpDown and I want to increment/decrement the value from them by 0.01. I tried to use NumericUpDownObject.Increment=0.01M, but there is no change after that, the value don't change. This is the code:
namespace Proiect1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int i = 1;
int o = 1;
private void button1_Click(object sender, EventArgs e)
{
Label l = new Label();
Label l2 = new Label();
NumericUpDown t = new NumericUpDown();
NumericUpDown t2 = new NumericUpDown();
l.Top = i * 25;
l.Left = 3;
l2.Top = i * 25;
l2.Left = 63;
t.Value = 0;
t.Increment = 0.01M;
t.Top = i * 25;
t.Left = 30;
t2.Value = 0;
t2.Top = i * 25;
t2.Left = 90;
i++;
t.Size =new System.Drawing.Size(30, 30);
t2.Size = new System.Drawing.Size(30, 30);
l.Size = new System.Drawing.Size(25, 20);
l2.Size = new System.Drawing.Size(29, 20);
l.Text = "n" + o;
l2.Text = "w" + o;
o++;
panel1.Controls.Add(t);
panel1.Controls.Add(t2);
panel1.Controls.Add(l);
panel1.Controls.Add(l2);
panel1.AutoScroll = true;
}
Try this
This will setup the whole form when it's created, but only increment when clicked.
It looks like your solution is re-creating everything each time it's clicked.
P.s apols - been a while since I did Winforms/WPF
namespace Proiect1
{
public partial class Form1 : Form
{
NumericUpDown _t = new NumericUpDown();
NumericUpDown _t2 = new NumericUpDown();
Label _l = new Label();
Label _l2 = new Label();
public Form1()
{
InitializeComponent();
int i = 1;
int o = 1;
_l.Top = i * 25;
_l.Left = 3;
_l2.Top = i * 25;
_l2.Left = 63;
_t.Value = 0;
_t.Increment = 0.01;
_t.Top = i * 25;
_t.Left = 30;
_t2.Value = 0;
_t2.Top = i * 25;
_t2.Left = 90;
i++;
_t.Size =new System.Drawing.Size(30, 30);
_t2.Size = new System.Drawing.Size(30, 30);
_l.Size = new System.Drawing.Size(25, 20);
_l2.Size = new System.Drawing.Size(29, 20);
_l.Text = "n" + o;
_l2.Text = "w" + o;
o++;
panel1.Controls.Add(_t);
panel1.Controls.Add(_t2);
panel1.Controls.Add(l_);
panel1.Controls.Add(l_2);
panel1.AutoScroll = true;
}
private void button1_Click(object sender, EventArgs e)
{
_t.Increment = 0.01;
}

How to use properties of text boxes outside of the current context in visual studio [duplicate]

I have created WinForm App in which user can set how many textboxes he want (Range 1-99)
I am using this code to create Textboxes during runtime
for (int i = 0; i < Calculation.Num; i++)
{
TextBox txtRun = new TextBox();
txtRun.Name = "txtBox" + i;
txtRun.Location = new System.Drawing.Point(35, 50 + (20 * i) * 2);
txtRun.Size = new System.Drawing.Size(75, 25);
this.Controls.Add(txtRun);
}
Suppose user create 2 textboxes and then enter data in each textbox and click calculate button
Now i want to get the textboxes data and divide it by 100
See The Picture I want txtbox1 and txtbox2 data
EDIT 3:
This is the Whole Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace GPA_Calculatior__New_
{
public partial class Form1 : Form
{
int j = 0;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//Label + Marks Obtained Textbox
for (int i = 0; i < Calculation.Num; i++)
{
Label lblCount = new Label();
lblCount.Name = "lblCount" + i;
lblCount.Location = new System.Drawing.Point(5, 55 + (20 * i) * 2);
lblCount.Size = new System.Drawing.Size(20, 30);
lblCount.Text = (i + 1).ToString();
this.Controls.Add(lblCount);
TextBox txtRun = new TextBox();
txtRun.Name = "txtBox" + i;
txtRun.Location = new System.Drawing.Point(35, 50 + (20 * i) * 2);
txtRun.Size = new System.Drawing.Size(75, 25);
this.Controls.Add(txtRun);
}
//Creating Textbox which is for total marks
for (j = 0; j < Calculation.Num; j++)
{
TextBox txtRun = new TextBox();
txtRun.Name = "TotaltxtBox" + j;
txtRun.Location = new System.Drawing.Point(160, 50 + (20 * j) * 2);
txtRun.Size = new System.Drawing.Size(50, 25);
txtRun.Text = "100";
txtRun.Enabled = false;
this.Controls.Add(txtRun);
}
// Creating 2 Buttons (Calculate and Back)
for (int k = 0; k < 2; k++)
{
Button Btn = new Button();
Btn.Name = "btn" + k;
Btn.Location = new System.Drawing.Point(20 + (k *110), 60 + (20 * j) * 2);
Btn.Size = new System.Drawing.Size(90, 30);
if (k == 0)
Btn.Text = "Back";
else
Btn.Text = "Calculate";
Btn.Click += button_Click;
this.Controls.Add(Btn);
}
//Just for Giving free space in last
Label lbl = new Label();
lbl.Name = "lbl" + j;
lbl.Location = new System.Drawing.Point(30, 90 + (20 * j) * 2);
lbl.Size = new System.Drawing.Size(90, 30);
lbl.Text = "";
this.Controls.Add(lbl);
//**********************************************
}
//Caculate and back button function
private void button_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
if (btn.Name.Equals("btn1"))
{
for (int i = 0; i < Calculation.Num; i++)
{
}
}
else
{
GPA_Calculator mainForm = new GPA_Calculator();
mainForm.Show();
this.Hide();
}
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
for (j = 0; j < 10; j++)
{
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
Application.Exit();
}
}
}
var sum = this.Controls.OfType<TextBox>()
.Where(t => char.IsDigit(t.Name.Reverse().Take(1).FirstOrDefault())
&& t.Enabled)
.Select(t =>
{
double i;
if (!double.TryParse(t.Text, out i)) { return 0d; }
return i / 100d;
})
.Sum();
This may work, I built a separate class to store the control and its value, then you can work out the values independently from the rest of the form. You need to trigger the calculations though:
private List<InfoTextBox> activeTextBoxes = new List<InfoTextBox>();
public Form1()
{
for (int i = 0; i < Calculation.Num; i++)
{
TextBox txtRun = new TextBox();
txtRun.Name = "txtBox" + i;
txtRun.Location = new System.Drawing.Point(35, 50 + (20 * i) * 2);
txtRun.Size = new System.Drawing.Size(75, 25);
this.Controls.Add(txtRun);
InfoTextBox iBox = new InfoTextBox();
iBox.textbox = txtRun;
activeTextBoxes.Add(iBox);
}
}
public class InfoTextBox
{
private double _textboxValue;
public TextBox textbox { get; set; }
public double TextBoxValue { get { return _textboxValue; } set { _textboxValue = setValue(value); } }
private double setValue(double invalue)
{
return invalue / 100;
}
}

C# - How can I create 2 separate button arrays with different controls without them causing problems with the other?

I am currently trying to develop a form of battleships on c# windows form.
Here is the code I am trying to use.. the trouble I have been having is how to create a second set of buttons (another 10x10) behind the other, with two sets of controls so I can switch between the two.
I have everything like AI and automated setups, I just need to have 2 button controls. I hope someone can help me out with this! Many thanks!
private List<List<Button>> grid = new List<List<Button>>();
public UserForm()
{
InitializeComponent();
byte numRows = 10;
byte numCols = 10;
for (byte i = 0; i < numRows; i++)
{
grid.Add(ButtonRowCreator(numCols, 25, (i+1) * 50));
}
}
public List<Button> ButtonRowCreator(byte numOfBtnsNeeded, int x, int y)
{
List<Button> btns = new List<Button>();
for (int i = 0; i < numOfBtnsNeeded; i++)
{
Button btn = new Button();
btn.Size = new Size(50, 50);
btn.Location = new Point(x + (i * btn.Width), y);
btns.Add(btn);
btn.Font = new Font("Georiga", 10);
this.Controls.Add(btn);
btn.Click += new EventHandler(btn_Click);
}
return btns;
}
void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
int curRow = -1, curCol = -1;
for(int i = 0; i < grid.Count; i++)
{
int index = grid[i].IndexOf(btn);
if (index != -1)
{
curRow = i;
curCol = index;
Console.WriteLine("curRow = " + curRow.ToString() + ", curCol = " + curCol.ToString());
}
}
// ... now you can use "curRow", "curCol" and "grid" to do something ...
foreach (List<Button> row in grid)
{
foreach (Button col in row)
{
col.ForeColor = Color.Gray;
}
}
if (board[curRow, curCol] == 1)
{
if (btn.Text == "Hit")
{
}
else
{
btn.Text = "Hit";
btn.BackColor = Color.Red;
hit++;
}
if (hit == 17)
{
MessageBox.Show("Congratulations, You Sunk Their Battleships!");
MessageBox.Show("Thanks For Playing!");
MessageBox.Show("Goodbye!");
}
}
else
{
btn.Text = "Miss!";
btn.BackColor = Color.Blue;
}
I think this is what you're after?
It looks like a lot of your code is used to figure out what button is clicked on. This information can be stored on the button object itself in the Tag property and greatly simplifies the code.
private Button[,] _grid1;
private Button[,] _grid2;
public UserForm()
{
InitializeComponent();
_grid1 = new Button[10, 10];
_grid2 = new Button[10, 10];
CreateGrid(_grid1, 10, 10, 25, 0, 20, true);
CreateGrid(_grid2, 10, 10, 25, 250, 20, false);
}
public void CreateGrid(Button[,] grid, int numOfRows, int numOfCols, int offsetX, int offsetY, int buttonSize, bool enabled)
{
for (byte i = 0; i < numOfRows; i++)
{
for (byte j = 0; j < numOfCols; j++)
{
grid[i,j] = ButtonCreator(i, j, offsetX, offsetY, buttonSize, enabled);
}
}
}
public Button ButtonCreator(int row, int col, int x, int y, int buttonSize, bool enabled)
{
Button btn = new Button();
btn.Size = new Size(buttonSize, buttonSize);
btn.Location = new Point(x + (col * buttonSize), y + (row * buttonSize));
btn.Font = new Font("Georiga", 10);
this.Controls.Add(btn);
btn.Click += new EventHandler(btn_Click);
btn.Tag = row + "," + col;
btn.Enabled = enabled;
return btn;
}
void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
string[] coord = btn.Tag.ToString().Split(',');
int curRow = Convert.ToInt32(coord[0]);
int curCol = Convert.ToInt32(coord[1]);
Console.WriteLine(curRow = " + curRow + ", curCol = " + curCol);
// ... now you can use "curRow", "curCol" to do something ...
_grid1[curRow, curCol].BackColor = Color.Red;
}

C# deleting dynamic textboxes by checkboxing

I am writing a code in C# I have 2 Forms and the code creates textboxes and corresponding checkboxes dynamically. The code I wrote creates dynamic textboxes and checkboxes successfully. However, I am not able to delete the row of textboxes in a selected checkbox line.
public void CreateTextBox(int i, StringReader sr)
{
ProductForm form2 = new ProductForm();
_cb = new CheckBox[i];
form2.Visible = true;
form2.Activate();
int x = 10;
int y = 30;
int width = 100;
int height = 20;
for (int n = 0; n < i; n++)
{
String line = sr.ReadLine();
String[] line_ = line.Split(new char[] {'\t'});
String cbName = "chkBox_" + n.ToString();
_cb[n] = new CheckBox();
_cb[n].Name = cbName;
_cb[n].Location = new Point(2, y);
_cb[n].Checked = false;
form2.Controls.Add(_cb[n]);
if (line.Length > 3)
{
for (int row = 0; row < 4; row++)
{
String name = "txtBox_" + row.ToString();
TextBox tb = new TextBox();
tb.Name = name;
tb.Text = line_[row].ToString();
tb.Location = new Point(x, y);
tb.Height = height;
if (row == 1)
{
tb.Width = width * row;
}
if (row == 3)
{
tb.Width = width * 5;
}
else
{
tb.Width = width - 20;
}
x += 10 + width;
form2.Controls.Add(tb);
}
}
x = 10;
y += 25;
}
}
private void DeleteTextBoxButton_Click(object sender, EventArgs e)
{
//Here should I add a code in order to delete dynamically created
//textboxes by clicking checkbox and button
}
}
Not sure of your question. But if I am right, this could do the trick.
SOLUTION1: While creating all the controls, add them to a List<Controls>. When you are checking the checkbox to delete the row, get the name of the checkbox, search it in the List<Controls>. So this way can get the index of the row of the checkbox clicked. Now delete the controls of that rows.
SOLUTION2: Create your controls in a TablelayoutPanel and everything will be easy.
EDIT
Copy paste everything in the form1, se btn_click as a event handler for a button. Let the size of the form a bit big. Everything should work fine now. If not working, let me know.
class MyControl
{
public TextBox txt1 { get; set; }
public TextBox txt2 { get; set; }
public TextBox txt3 { get; set; }
public TextBox txt4 { get; set; }
public CheckBox cb { get; set; }
public MyControl(TextBox txt1, TextBox txt2, TextBox txt3, TextBox txt4, CheckBox cb)
{
this.txt1 = txt1;
this.txt2 = txt2;
this.txt3 = txt3;
this.txt4 = txt4;
this.cb = cb;
}
}
List<MyControl> list = new List<MyControl>();
public int x = 50, n = 1;
TextBox txtTemp, txt1, txt2, txt3, txt4;
CheckBox cbTemp;
private void btn_Click(object sender, EventArgs e)
{
txtTemp = new TextBox();
txtTemp.Location = new System.Drawing.Point(10, x);
txtTemp.Name = "txt1_" + n;
txt1 = txtTemp;
txtTemp = new TextBox();
txtTemp.Location = new System.Drawing.Point(120, x);
txtTemp.Name = "txt2_" + n;
txt2 = txtTemp;
txtTemp = new TextBox();
txtTemp.Location = new System.Drawing.Point(230, x);
txtTemp.Name = "txt3_" + n;
txt3 = txtTemp;
txtTemp = new TextBox();
txtTemp.Location = new System.Drawing.Point(350, x);
txtTemp.Name = "txt4_" + n;
txt4 = txtTemp;
cbTemp = new CheckBox();
cbTemp.Name = "cb1_" + n;
cbTemp.Enter += new EventHandler(cbTemp_Enter);
cbTemp.Location = new System.Drawing.Point(490, x);
this.Controls.Add(txt1);
this.Controls.Add(txt2);
this.Controls.Add(txt3);
this.Controls.Add(txt4);
this.Controls.Add(cbTemp);
list.Add(new MyControl(txt1, txt2, txt3, txt4, cbTemp));
x += 40;
n++;
}
void cbTemp_Enter(object sender, EventArgs e)
{
if ((MessageBox.Show("Are you Sure?", "Warning", MessageBoxButtons.YesNo)) == DialogResult.No)
return;
CheckBox cbMain = (CheckBox)sender;
int index = Search(cbMain);
this.Controls.Remove(list[index].txt1);
this.Controls.Remove(list[index].txt2);
this.Controls.Remove(list[index].txt3);
this.Controls.Remove(list[index].txt4);
this.Controls.Remove(list[index].cb);
}
private int Search(CheckBox cbMain)
{
int temp = 0;
foreach (MyControl item in list)
{
if(cbMain.Name == item.cb.Name)
temp = list.IndexOf(item);
}
return temp;
}
For WinForms, I recommend putting the generated TextBoxes into the Tag field of the CheckBox. Then keep a managed list of all CheckBoxes. Once they click the delete button, iterate through the collection of CheckBoxes. If their state is checked, pull the TextBox out of the Tag field, remove it from the form collection, then delete it.
NOTE: This code is untested but should work in principle.
UPDATE: Reading your latest comment, instead of storing a single TextBox in the Tag, just create another List of them and store the entire list in the tag. Then iterate through those in the delete method.
private List<CheckBox> _checkboxes = new List<CheckBox>();
public void CreateTextBox( int i, StringReader r )
{
// ... do your stuff here
_cb[n].Tag = tb;
// ... finish up
_checkboxes.Add( _cb[n] );
}
public void DeleteTextBoxButton_Click( object sender, EventArgs e )
{
foreach( var cb in _checkboxes )
{
if( cb.Checked )
{
TextBox tb = cb.Tag as TextBox;
if( tb != null )
{
form2.Controls.Remove( tb );
}
}
}
}

Categories