Array of buttons: change property - c#

I have an array of buttons, like this:
int x = 0, y = 0;
butt2 = new Button[100];
for (int i = 0; i < 100; i++)
{
butt2[i] = new Button();
int names = i;
butt2[i].Name = "b2" + names.ToString();
butt2[i].Location = new Point(525 + (x * 31), 70 + (y * 21));
butt2[i].Visible = true;
butt2[i].Size = new Size(30, 20);
butt2[i].Click += new EventHandler(butt2_2_Click); //problem lies here (1)
this.Controls.Add(butt2[i]);
}
private void butt2_2_Click(object sender, EventArgs e)
{
// want code here
}
I want to change the back color of the button when clicked. I was thinking of passing i to be able to do this:
butt2[i].BackColor = Color.Green;

This should do the trick:
private void butt2_2_Click(object sender, EventArgs e)
{
Button pushedBtn = sender as Button;
if(pushedBtn != null)
{
pushedBtn.BackColor = Color.Green;
}
}
And this holds for most UI events, the 'object sender' parameter refers to the control that 'sent'/'fired' the event.
To learn more about C# event handling, I would start here.
Also, here is a SO question about GUI event handling, answered nicely by Juliet (accepted answer).
Hope this helps.

Related

how to create a list of events for a list of buttons c#?

i have a List of Buttons ... but i want to make an events for each button in the list --i have tried this code
ButtonName.Click += (sender, args) =>
{
Point p = new Point(20 * j, 70);
Product[j].Location = p;
Product[j].Width = 200;
Product[j].Height = 250;
this.Controls.Add(Product[j]);
};
the event i want to make is that when click on any button it should show a List Box which is related to this button.
and every List box have its own data .... the only problem i want to get a solution for it is to make event for every button in list
is that possible ??
Update
for (int j = 0; j < Data.BTN_Name.Count; j++)
{
Category[j].Click += (sender, args) =>
{
Point p = new Point(20 * j, 70);
Product[j].Location = p;
Product[j].Width = 200;
Product[j].Height = 250;
this.Controls.Add(Product[j]);
};
It seems to me that you want to do this:
for (int j = 0; j < Data.BTN_Name.Count; j++)
{
Product[j] = new ListBox()
{
Location = new Point(20 * j, 70),
Width = 200,
Height = 250,
Visible = false,
};
this.Controls.Add(Product[j]);
var captured_j = j;
Category[j].Click += (s, ea) => Product[captured_j].Visible = true;
}
You must capture the j variable to use it in the event handler - hence the code var captured_j = j; just before the event handler.
As I can see, you are actualy trying to tie a some button to some listbox. As #TheGeneral said, you can use a Tag property of button, but I don't like this approach (although it has the right to be, it is just a matter of habit). Here is my example:
public class YourForm : Form
{
private IDictionary<Button, ListBox> _listboxes = new Dictionary<Button, ListBox>();
// use this if you create a button and listbox simultaneously
protected void CreateButtonAndList()
{
var listbox = new ListBox();
// initialize listbox as needed
var button = new Button();
// initialize button as needed
button.Click += ButtonClickHandler;
_listboxes.Add(button, listbox);
}
// use this if you create a button for already existing listbox
protected void CreateButtonFor(ListBox listbox)
{
var button = new Button();
// initialize button as needed
button.Click += ButtonClickHandler;
_listboxes.Add(button, listbox);
}
private void ButtonClickHandler(object sender, EventArgs e)
{
var listbox = _listboxes[sender];
// do what you want with listbox
}
}
Also note, that you probably doesn't need both CreateButtonAndList() and CreateButtonFor() methods. You may leave only one that fit your needs.

I can not go to "EventHandler" with double click

When btnAsset is double-clicked, it should go to allButton_Click.
But it only goes in one click. how can I do that?
public void Add(MainForm frm)
{
this.form1 = frm;
for (int i = 0; i < 10; i++)
{
btnAsset[i] = new Button();
btnAsset[i].Tag = i;
btnAsset[i].Name = "Asset-" + i.ToString();
btnAsset[i].Width = 150;
btnAsset[i].Height = 120;
btnAsset[i].Visible = true;
btnAsset[i].BackColor = Color.GreenYellow;
form1.flowLayoutVideo.Controls.Add(btnAsset[i]);
btnAsset[i].DoubleClick += new EventHandler(allButton_Click);
}
}
should go here when double clicked
void allButton_Click(object sender, EventArgs e)
{
Button p = sender as Button;
if (p != null)
{
int i = (int)p.Tag;
MessageBox.Show((i + 1).ToString() + ". seçildi");
}
}
Look what the docs says about it:
By default, the ControlStyles.StandardClick and ControlStyles.StandardDoubleClick style bits are set to false for the Button control, and the DoubleClick event is not raised.
You can change this behaviour by creating your own button class deriving from Button and change the style bits.

Defining an event handler where the sender was dynamically added [duplicate]

This question already has answers here:
How to add event handler for dynamically created controls at runtime?
(3 answers)
How to add an event to a UserControl in C#?
(6 answers)
Closed 3 years ago.
I am trying to write a C# program that plays checkers. So far I've completed all the "Shallow" things such as generating the board and all the labels etc.
My problem is that all the controls are dynamically added. So I can't just "double click" them and define what to do at Button_Click event.
This is my code for generating the form
public partial class formGameBoard : Form
{
private readonly int m_BoardSize;
private readonly string m_Player1Name;
private readonly string m_Player2Name;
private GameTile m_BlueTile;
private bool m_IsThereBlue;
public formGameBoard(int i_BoardSize, string i_Player1Name, string i_Player2Name)
{
m_BoardSize = i_BoardSize;
m_Player1Name = i_Player1Name;
m_Player2Name = i_Player2Name;
if (m_Player2Name == "(Computer)")
{
m_Player2Name = "Computer";
}
m_IsThereBlue = false;
InitializeComponent();
}
private void formGameBoard_Load(object sender, EventArgs e)
{
int SizeOfButton = 60;
int ButtonRowindex = 0;
int ButtonColindex = 0;
this.Size = new System.Drawing.Size(30 + m_BoardSize * SizeOfButton, 100 + m_BoardSize * SizeOfButton);
Button[,] PlayButtonArray = new Button[m_BoardSize, m_BoardSize];
for (ButtonRowindex = 0; ButtonRowindex < m_BoardSize; ButtonRowindex++)
{
for (ButtonColindex = 0; ButtonColindex < m_BoardSize; ButtonColindex++)
{
PlayButtonArray[ButtonRowindex, ButtonColindex] = new Button();
PlayButtonArray[ButtonRowindex, ButtonColindex].Size = new Size(SizeOfButton, SizeOfButton);
PlayButtonArray[ButtonRowindex, ButtonColindex].Left = 10 + ButtonRowindex * SizeOfButton;
PlayButtonArray[ButtonRowindex, ButtonColindex].Top = 50 + ButtonColindex * SizeOfButton;
if ((ButtonRowindex + ButtonColindex) % 2 == 0)
{
PlayButtonArray[ButtonRowindex, ButtonColindex].Enabled = false;
PlayButtonArray[ButtonRowindex, ButtonColindex].BackColor = Color.Gray;
}
this.Controls.Add(PlayButtonArray[ButtonRowindex, ButtonColindex]);
}
}
FillButtons(PlayButtonArray);
}
public void FillButtons(Button[,] ButtonMatrix)
{
int i, j;
for (i = 0; i < m_BoardSize; i++)
{
for (j = 0; j < m_BoardSize; j++)
{
if ((i + j) % 2 == 1)
{
if (j <= (m_BoardSize / 2) - 2)
{
ButtonMatrix[i, j].Text = "O";
}
if (j > (m_BoardSize / 2))
{
ButtonMatrix[i, j].Text = "X";
}
}
}
}
}
struct GameTile
{
int RowIndex;
int ColumnIndex;
}
}
}
I have no issues with it, it looks very nice in my opinion
My problem is that all those buttons are dynamically added. I didnt drag and drop them. I created them at form load. Now I want something to happen when I click a button. For example, I want the button I clicked to change its color to blue.
How can I do that?
Adding the click event for a button is very simple, like this:
buttonName.Click += (sender, e) => { buttonName.Foreground = Colors.Blue; };
Or if you want to make it a method that will handle many button clicks, you could do this:
buttonName.Click += YourButtonHandler;
private void YourButtonHandler(object sender, EventArgs e)
{
// do something, for example:
Button b = sender as Button;
b.Foreground = Colors.Blue;
}
You can add a handler to Click event of your buttons and use sender parameter.
Also probably the index of button in the array is important for you, so you can store array index of the button in Tag property and use it later.
In the for loop:
var button = PlayButtonArray[ButtonRowindex, ButtonColindex];
button.Tag= new Point(ButtonRowindex, ButtonColindex);
button.Click += Button_Click;
Code for Button_Click:
private void Button_Click(object sender, EventArgs e)
{
var button = sender as Button;
//You can manipulate button here
//Also to extract the button index in array:
var indexes = (Point)button.Tag;
MessageBox.Show(string.Format("This is the button at {0}, {1}", indexes.X, indexes.Y));
}

Reference a button outside of a loop?

This function dynamically creates nine buttons for use in a game I am making. You can see what attributes I give to the button.
private void createbuttons()
{
int tot = 0;
int x = 100;
int y = 100;
while(tot < 9)
{
string buttonsname = (tot + "button").ToString();
Button creating = new Button();
creating.Name = buttonsname;
creating.Size = new Size(100, 100);
creating.Click += delegate
{
MessageBox.Show("You clicked me!");
};
creating.Text = buttonsname;
if(x > 300)
{
y += 100;
x = 100;
}
creating.Location = new Point(x, y);
Controls.Add(creating);
tot += 1;
x += 100;
}
}
What I want to know is how to reference these buttons in different parts of the same form. Specifically when 'Start Game' is clicked I want to change the text for each button to something different.
private void button10_Click(object sender, EventArgs e)
{
//What would I write here to change the text?
}
You can access the buttons by enumerating the controls, or you could create a list of buttons for future reference, and use that list later.
Here is how you do it with a list:
private IList<Button> addedButtons = new List<Button>();
private void createbuttons() {
int tot = 0;
int x = 100;
int y = 100;
while(tot < 9) {
string buttonsname = (tot + "button").ToString();
Button creating = new Button();
creating.Name = buttonsname;
creating.Size = new Size(100, 100);
creating.Click += delegate {
MessageBox.Show("You clicked me!");
};
creating.Text = buttonsname;
if(x > 300) {
y += 100;
x = 100;
}
creating.Location = new Point(x, y);
addedButtons.Add(creating); // Save the button for future reference
Controls.Add(creating);
tot += 1;
x += 100;
}
}
Now you can do this:
foreach (var btn : addedButtons) {
btn.Text = "Changed "+btn.Text;
}
The form has a property Controls that holds all child controls. To find a child control by its Name property use method Find, which returns the array, because there may be several control with the same Name, but if you make sure that names exist, are unique, and you know their type (Button) you can just take the first item from the array and cast it:
private void button10_Click(object sender, EventArgs e)
{
Button buttonNamedFred = (Button)this.Controls.Find("Fred", false)[0];
buttonNamedFred.Text = "I'm Fred";
}

C# - Click event sending a value

I'm using a for-loop to add values into an array of PictureBox and binding a click event to each one. I'm looking for a way of getting the data of a PictureBox after clicking on it. Since it's an array, I was thinking of sending the value of the loop counter, which would identify which one was clicked.
My code looks like this:
PictureBox[] picboxes = new PictureBox[result];
for (int i = 0; i < results; i++)
{
picboxes[i] = new PictureBox();
picboxes[i].ImageLocation = #FormIni.RetRes((i * 5) + 5 + i);
picboxes[i].Click += new System.EventHandler(PictureBoxes_Click);
}
private void PictureBoxes_Click(object sender, EventArgs e)
{
label1.Text = "here I need the value of the picboxes[i] image location";
}
It can seem stupid, but I thought of something like:
picboxes[i].Click += new System.EventHandler(PictureBoxes_Click(i))
and
private void PictureBoxes_Click(object sender, EventArgs e, int i)
In short: when I click in a PictureBox created in a array via code, how do I get its values (inside the click event handler)?
EDIT!
Sorry for finding it only after making this question, but I've found this solution and it may apply to my case, right?
try do do this
PictureBox[] picboxes = new PictureBox[result];
for (int i = 0; i < results; i++)
{
picboxes[i] = new PictureBox();
picboxes[i].Name = (i+1).ToString();
picboxes[i].ImageLocation = #FormIni.RetRes((i * 5) + 5 + i);
picboxes[i].Click += new System.EventHandler(PictureBoxes_Click);
}
private void PictureBoxes_Click(object sender, EventArgs e)
{
PictureBox p = (PictureBox)sender;
string j = p.Name;
label1.Text = j;
}
You can use the following (anoynomous method) lambda expression
picboxes[i].Click += (sender, eventArguments) => PictureBoxes_Click(sender, eventArguments, i);
Use Tag
PictureBox[] picboxes = new PictureBox[result];
for (int i = 0; i < results; i++)
{
picboxes[i] = new PictureBox();
picboxes[i].Tag = (i+1).ToString();
picboxes[i].ImageLocation = #FormIni.RetRes((i * 5) + 5 + i);
picboxes[i].Click += new System.EventHandler(PictureBoxes_Click);
}
private void PictureBoxes_Click(object sender, EventArgs e)
{
PictureBox p = (PictureBox)sender;
string j = p.tag.tostring();
label1.Text = j;
}

Categories

Resources