I have an action for my button in c# Winform like this:
private void btnAction_Click(object sender, EventArgs e)
{
TextBox tbxdg = new TextBox();
tbxdg.Name = "tbx_DG" + cx.ToString();
tbxdg.Location = new Point(508, 12 + (40 * cx));
tbxdg.Size = new Size(200, 24);
tbxdg.Font = new Font("Tahoma", 10);
panel2.Controls.Add(tbxdg);
cx++;
}
Now I want to get text from the textbox that i've created by clicking my button. I've tried call the textbox by the name that i given to it in the button click action but it's not working.
u can try this:
var textBoxText = panel2.Controls.Find("name of textbox", false).First().Text;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private int cx = 0;
private void button1_Click(object sender, EventArgs e)
{
TextBox tbxdg = new TextBox();
tbxdg.Name = "tbx_DG" + cx.ToString();
tbxdg.Location = new Point(0, 0 + (40 * cx));
tbxdg.Size = new Size(200, 24);
tbxdg.Font = new Font("Tahoma", 10);
panel1.Controls.Add(tbxdg);
cx++;
}
private void button2_Click(object sender, EventArgs e)
{
label1.Text = string.Empty;
foreach (TextBox tb in panel1.Controls)
{
label1.Text += $"{tb.Name} - {tb.Text}\n";
}
}
}
Demo
Instead of searching the control name in the panel, another approach is to add all the dynamic text boxes to global List<TextBox>
Please read comments inside the example:
private int cx;
private List<TextBox> DynamicTextBoxesList = new List<TextBox>();
private void btnAction_Click(object sender, EventArgs e)
{
TextBox tbxdg = new TextBox();
tbxdg.Name = "tbx_DG" + cx.ToString();
tbxdg.Location = new Point(508, 12 + (40 * cx));
tbxdg.Size = new Size(200, 24);
tbxdg.Font = new Font("Tahoma", 10);
panel2.Controls.Add(tbxdg);
// add to list
DynamicTextBoxesList.Add(tbxdg);
cx++;
}
// button event for example how to use DynamicTextBoxesList
private void btnExampleFoaccesingTextBoxes_Click(object sender, EventArgs e)
{
if (DynamicTextBoxesList.Count > 0)
{
foreach (TextBox t in DynamicTextBoxesList)
{
MessageBox.Show(t.Text);
}
// or you can find by name for example you need cx=1:
var txtbox = DynamicTextBoxesList.Where(x => x.Name == "tbx_DG1").FirstOrDefault();
if (txtbox != null)
{
MessageBox.Show(txtbox.Text);
}
}
}
Related
I have created a windows form application, where it adds some button when the form1 is loaded. I want to change the color of the form1 button when the form2 button is clicked
Point newLoc = new Point(20, 35);
int ButtonHeight = 0;
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 1; i < 20; i++)
{
Button b = new Button
{
Name = "Btn" + i.ToString(),
Size = new Size(120, 60),
Location = newLoc, Text = i.ToString(),
BackColor = System.Drawing.Color.PaleGreen
};
i++;
if ((i % 10) == 0)
{
ButtonHeight = ButtonHeight + b.Height + 10;
newLoc = new Point(-110, 25 + ButtonHeight);
}
newLoc.Offset(b.Width + 10, 0);
Controls.Add(b);
}
}
public void Changecolor(Button b)
{
b.BackColor = System.Drawing.Color.Yellow;
}
private void Form1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.Show();
}
//form2
private void button1_Click(object sender, EventArgs e)
{
Button b = new Button
{
Name = "Btn" + textBox1.Text
};
Form1 f1 = new Form1();
f1.Change_color(b);
}
if i type a number in form2.textbox and click form2.button. it should change the backcolor of form1.button with the name "Btn" + textBox1.Text
button.BackColor = Color.Red
where ever you want it to happen
When you call other function with new keyword, normally you cannot change their property.
You need to declare one object for opener form and set it's component like below (please change names for yours, it's going to be working for you):
//In form 2:
var frmName= (frmName)Application.OpenForms["frmName"];
frmName.Button1.BackColor=Color.Red
Edit: Yes you can access button which created dynamically but need to change access modifier to public.
// In form1:
public Button b =new Button();
private void button8_Click(object sender, EventArgs e)
{
b.Name = "btn";
b.Size = new Size(120, 60);
b.Text = "denemee";
b.BackColor = System.Drawing.Color.PaleGreen;
Controls.Add(b);
}
I have a bounded DataGridView. How can I add a button in one field with data? I will attach a screenshot of how I see it. Do you have any recommendations on this?
it's WinForms and I think that I need to write a custom column type.
I don't think the standard DataGridViewColumn subclasses provide what you're after.
It can be done, though: you will have to create your own custom Control (I guess a TextBox with a Button right next to it), and the appropriateDataGridViewColumn and DataGridViewCell subclasses to host your custom control.
Follow the documentation for further details.
Of course, the alternative would be using third-party, smarter grids.
Create custom column:
class TextAndButtonControl : UserControl
{
private TextBox textbox1;
private Button button1;
public TextAndButtonControl()
{
this.textbox1 = new TextBox();
this.Controls.Add(this.textbox1);
this.button1 = new Button();
this.Controls.Add(this.button1);
this.RenderControl();
this.button1.Click += new EventHandler(button1_Click);
}
void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Hi");
}
public string Text
{
get { return this.textbox1.Text; }
set { this.textbox1.Text = value; }
}
public string ButtonText
{
get { return this.button1.Text; }
set { this.button1.Text = value; }
}
public void RenderControl()
{
this.textbox1.Location = new Point(0, 0);
this.textbox1.Width = 2 * this.Width / 3;
this.textbox1.Height = this.Height;
this.button1.Location = new Point(2 * this.Width / 3, 0);
this.button1.Width = this.Width / 3;
this.button1.Height = this.Height;
}
}
Add the control in the following way
private void Form1_Load(object sender, EventArgs e)
{
TextAndButtonControl bcol = new TextAndButtonControl();
bcol.Text = "Button Column ";
bcol.ButtonText = "Click Me";
bcol.Name = "btnClickMe";
bcol.RenderControl();
dgMainGrid.Controls.Add(bcol);
}
There is a DataGridViewButtonColumn-Type (Or if you just want a single Cell as Button -> DataGridViewButtonCell-Type).
You could create the DataGridButtonColumn and then add it to your DataGridView:
DataGridViewButtonColumn tempBtnColumn = new DataGridViewButtonColumn();
tempBtnColumn.HeaderText = "Button";
tempBtnColumn.Text = "Button-Text";
tempBtnColumn.Name = "Button-Name";
tempBtnColumn.UseColumnTextForButtonValue = true;
Grid.Columns.Add(tempBtnColumn);
//or if you want a specified position for the Grid:
Grid.Columns.Insert(0, tempBtnColumn);
Update
Here is an update, you could give the ButtonCell the Value you want and then read that with CurrentCell.Value (here is a example, hope it's understandable):
private void ButtonCellWithValue()
{
DataGridViewButtonCell dgvbc = new DataGridViewButtonCell();
dgvbc.Value = "1";
DataGridViewRow dgvr = new DataGridViewRow();
dgvr.Cells.Add(dgvbc);
dataGridView1.Rows.Add(dgvr);
dgvbc = new DataGridViewButtonCell();
dgvbc.Value = "2";
dataGridView1.Rows[0].Cells[1] = dgvbc;
GridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick);
}
void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (((DataGridView)sender).CurrentCell.Value == "1")
{
MessageBox.Show("Super");
}
else if (((DataGridView)sender).CurrentCell.Value == "2")
{
MessageBox.Show("Better");
}
}
Thank a lot #RavirajPalvankar.
If somebody will need, I will write the code here, because cann't write it to Ravuraj's comment, because it's long:
Use the class as Raviraj write:
class TextAndButtonControl : UserControl
{
private TextBox textbox1;
private Button button1;
public TextAndButtonControl()
{
this.textbox1 = new TextBox();
this.Controls.Add(this.textbox1);
this.button1 = new Button();
this.Controls.Add(this.button1);
this.renderControl();
this.button1.Click += new EventHandler(button1_Click);
}
void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Click! The value is:" + this.Text);
}
public string Text
{
get { return this.textbox1.Text; }
set { this.textbox1.Text = value; }
}
public string ButtonText
{
get { return this.button1.Text; }
set { this.button1.Text = value; }
}
public void renderControl()
{
this.textbox1.Location = new Point(0, 0);
this.textbox1.Width = 2 * this.Width / 3;
this.textbox1.Height = this.Height;
this.button1.Location = new Point(2 * this.Width / 3, 0);
this.button1.Width = this.Width / 3;
this.button1.Height = this.Height;
}
}
then in main Form:
private void Form1_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("col1");
dt.Columns.Add("col2");
for (int j = 0; j < 20; j++)
{
dt.Rows.Add("col1" + j.ToString(), "col2" + j.ToString());
}
this.dataGridView1.DataSource = dt;
this.dataGridView1.Columns[0].Width = 150;
this.txbtnControl = new TextAndButtonControl();
this.txbtnControl.Visible = false;
this.dataGridView1.Controls.Add(this.txbtnControl);
//Handle the cellbeginEdit event to show the usercontrol in the cell while editing
this.dataGridView1.CellBeginEdit += new DataGridViewCellCancelEventHandler(dataGridView1_CellBeginEdit);
}
TextAndButtonControl txbtnControl;
void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
if (e.ColumnIndex == 0 && e.RowIndex > -1 && e.RowIndex != this.dataGridView1.NewRowIndex)
{
Rectangle rect = this.dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true);
this.txbtnControl.Location = rect.Location;
this.txbtnControl.Size = rect.Size;
this.txbtnControl.Text = this.dataGridView1.CurrentCell.Value.ToString();
this.txbtnControl.ButtonText = "...";
this.txbtnControl.renderControl();
this.txbtnControl.Visible = true;
}
}
Any idea how to add a mouse click event to generated Textbox fields. Here is the code for generating TextBox fields:
private void button1_Click(object sender, EventArgs e)
{
TextBox textbox = new TextBox();
textbox.Location = new Point(60, 25 * count);
textbox.Size = new Size(301, 20);
textbox.Name = "textbox_" + (count + 1);
textbox.TextChanged += new System.EventHandler(this.TextBox_Changed);
panel1.Controls.Add(textbox);
count++;
if (count == 4)
{
MessageBox.Show("");
button1.Enabled = false;
}
}
The code below must be in the method that handles the mouse click event for every generated Textbox field:
TextBox txtName = (TextBox)this.Controls.Find("textbox_1", true)[0];
TextBox txth = (TextBox)this.Controls.Find("textbox_2", true)[0];
if (txtName != null)
{
}
I think you are looking for something like this:
int count = 0;
private void button1_Click(object sender, EventArgs e)
{
TextBox textbox = new TextBox();
textbox.Location = new Point(60, 25 * count);
textbox.Size = new Size(301, 20);
textbox.Name = "textbox_" + (count + 1);
textbox.MouseClick += new System.Windows.Forms.MouseEventHandler(this.TextBox_MouseClick);
textbox.TextChanged += new System.EventHandler(this.TextBox_Changed);
panel1.Controls.Add(textbox);
count++;
if (count == 4)
{
MessageBox.Show("");
button1.Enabled = false;
}
}
private void TextBox_MouseClick(object sender, MouseEventArgs e)
{
TextBox txtName = (TextBox)this.Controls.Find("textbox_1", true)[0];
TextBox txth = (TextBox)this.Controls.Find("textbox_2", true)[0];
if (txtName != null)
{
MessageBox.Show("Test");
}
}
When I preform a click on a TextBox this MessageBox window appears:
I would also change the TextBox_MouseClick method to :
private void TextBox_MouseClick(object sender, MouseEventArgs e)
{
Control[] txtName = this.Controls.Find("textbox_1", true);
Control[] txth = this.Controls.Find("textbox_2", true);
if ((TextBox)txtName[0] != null)
{
MessageBox.Show("Test");
}
}
Because if you create only one TextBox and perform a click on it you will get a System.IndexOutOfRangeException because the second TextBox isn't created so the array that holds you second TextBox is empty.
I have a window form where I am creating a list of Checkboxes. The number of checkboxes created are based upon how many items are returned from the database. I've been able to create the checkboxes; however, I am not sure how to add event handlers for these checkboxes. For example, I'd like to add an OnCheckedChanged or CheckStateChanged event. How can I add these events? Also, I would appreciate any other suggestion. I am a total newbie to programming.
private void Form1_Load(object sender, EventArgs e)
{
CheckBoxes = new CheckBox[listGroup.Count()];
for (int i = 0; i < listGroup.Count(); i++)
{
CheckBoxes[i] = new CheckBox();
CheckBoxes[i].Text = listGroup.ElementAt(i).GroupName;
CheckBoxes[i].Name = "txt" + listGroup.ElementAt(i).GroupName.Replace(' ', '_');
CheckBoxes[i].CheckedChanged += new EventHandler(CheckBoxes[i]+"_CheckedChanged");
CheckBoxes[i].Width = 200;
if (i == 0)
{
CheckBoxes[i].Location = new System.Drawing.Point(5, 10);
}
else if (i == 1)
{
CheckBoxes[i].Location = new System.Drawing.Point(5, 40);
}
else if (i == 2)
{
CheckBoxes[i].Location = new System.Drawing.Point(5, 80);
}
this.Controls.Add(CheckBoxes[i]);
}
}
private void Form1_Load(object sender, EventArgs e)
{
//...
CheckBoxes[i].CheckedChanged += checkBoxes_CheckedChanged;
CheckBoxes[i].CheckStateChanged += checkBoxes_CheckStateChanged;
}
void checkBoxes_CheckedChanged(object sender, EventArgs e)
{ //do stuff when checked changed }
void checkBoxes_CheckStateChanged(object sender, EventArgs e)
{ //do stuff when check state changed }
Note: this will give identical event handling for all of your checkboxes.
If you want to do different things for different textboxes, you have to name the eventhandler differently and define that eventhandler.
A more efficient way to set the location of your checkboxes
for (int i = 0; i < listGroup.Count(); i++)
{
CheckBoxes[i] = new CheckBox();
CheckBoxes[i].Text = listGroup.ElementAt(i).GroupName;
CheckBoxes[i].Name = "txt" + listGroup.ElementAt(i).GroupName.Replace(' ', '_');
CheckBoxes[i].CheckedChanged += new EventHandler(CheckBoxes[i] + "_CheckedChanged");
CheckBoxes[i].Width = 200;
//set location based on index of i
CheckBoxes[i].Location = new System.Drawing.Point(5, 10 + (i * 30));
this.Controls.Add(CheckBoxes[i]);
}
private void LoadNewCheckboxes()
{
dynamic listGroupCount = 10;
List<System.Windows.Forms.CheckBox> CheckBoxes = new List<System.Windows.Forms.CheckBox>();
for (int i = 0; i <= listGroupCount - 1; i++)
{
System.Windows.Forms.CheckBox chkbox = new System.Windows.Forms.CheckBox();
chkbox.Text = i.ToString();
//listGroup.ElementAt(i).GroupName
chkbox.Name = "txt" + i.ToString();
//listGroup.ElementAt(i).GroupName.Replace(" "c, "_"c)
chkbox.CheckedChanged += new EventHandler(chkbox_CheckedChanged);
chkbox.CheckStateChanged += new EventHandler(chkbox_CheckStateChanged);
chkbox.Width = 200;
chkbox.AutoSize = true;
this.Controls.Add(chkbox);
CheckBoxes.Add(chkbox);
if (i == 0)
{
chkbox.Location = new System.Drawing.Point(5, 10);
}
else
{
chkbox.Location = new System.Drawing.Point(5, (CheckBoxes[i - 1].Top + CheckBoxes[i - 1].Height + 10));
}
}
}
private void chkbox_CheckedChanged(object sender, EventArgs e)
{
System.Windows.Forms.CheckBox chkbox = (System.Windows.Forms.CheckBox)sender;
if (chkbox != null)
{
//do somthing
Debug.WriteLine("chkbox_CheckedChanged");
Debug.WriteLine(chkbox.Text);
Debug.WriteLine(chkbox.Checked.ToString());
Debug.WriteLine(chkbox.Name.ToString());
}
}
private void chkbox_CheckStateChanged(object sender, EventArgs e)
{
System.Windows.Forms.CheckBox chkbox = (System.Windows.Forms.CheckBox)sender;
if (chkbox != null)
{
//do somthing
Debug.WriteLine("chkbox_CheckStateChanged");
Debug.WriteLine(chkbox.Text);
Debug.WriteLine(chkbox.Checked.ToString());
Debug.WriteLine(chkbox.Name.ToString());
}
}
I have tried creating textboxes dynamically using lists. All i need now is, how can i reset all text boxes that i have created by hitting a reset button.
The following is my code:
public void button2_Click_1(object sender, EventArgs e)
{
int number = Convert.ToInt32(textBox2.Text);
List<TextBox> inputTextBoxes;
inputTextBoxes = new List<TextBox>();
for (int i = 1; i <= number; i++)
{
Label labelInput = new Label();
TextBox textBoxNewInput = new TextBox();
labelInput.Text = "Activity No: " + i;
labelInput.Location = new System.Drawing.Point(30, textBox2.Bottom + (i * 40));
labelInput.AutoSize = true;
textBoxNewInput.Location = new System.Drawing.Point(labelInput.Width+60, labelInput.Top - 3);
inputTextBoxes.Add(textBoxNewInput);
this.Controls.Add(labelInput);
this.Controls.Add(textBoxNewInput);
}
}
The answer is:
private void resetButton_Click(object sender,EventArgs e)
{
for (int i = 0; i <= inputTextBoxes.Length; i++)
{
inputTextBoxes[i].Text = "";
}
}
And you should declare inputTextBoxes is a class member which is same class' of buttons.
Move the following line outside the event handler function (outside the function but inside the class)
List<TextBox> inputTextBoxes;
Then on the reset button click
private void btnReset_Click(object sender, EventArgs e)
{
foreach(TextBox txt in inputTextBoxes)
{
this.Controls.Remove(txt);
}
inputTextBoxes.Clear();
}
Edit: Corrected the class type in foreach loop (from Button to TextBox)