How to know what Linklabel has been clicked? - c#

Background
I have created 8 linklabels which are created using a loop which gets data from a database.
Each record fills a linklabel.
How ever how can I distinguish what linklabel has been clicked on?
Code
for (int i = 0; i <= rowCount - 1; i++)
{
LinkLabel Linklabel = new LinkLabel();
Linklabel.Text = ds.Tables[0].Rows[i]["code"].ToString();
Linklabel.Height = 15;
Linklabel.Width = 50;
Linklabel.AutoSize = true;
Linklabel.Location = new Point(10, (i + 1) * 30);
tabControl1.TabPages[0].Controls.Add(Linklabel);
// Add an event handler to do something when the links are clicked.
Linklabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
tabControl1.SelectedTab = tabPage2;
}
When clicking on any of the 8 linklabels that are drawn the same thing will happen.
What I would like to happen?
When clicking on any of the linklabels I would like to change a label.text to what the contents of the clicked linklabel was.
For example
If the first linklabel.text=("one") is clicked on label1.text becomes one.
If the second linkedlabel.text=("two") is clicked on label1.text becomes two.

You could use the sender argument in the callback which will point to the actual LinkLabel being clicked:
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
label1.text = ((LinkLabel)sender).Text;
}

Related

Event on label is not updating the clicked label

I want to add a event for label when a specific label is pressed, but my event handler is not reacting to the clicked label.
I created a calender so when I click a date I want to highlight that date, that's the requirement.
for (Int32 i = 1; i <= Dayz; i++)
{
ndayz += 1;
lblDayz = new Label();
lblDayz.Text = i.ToString();
lblDayz.Cursor = Cursors.Hand;
lblDayz.Name = "Date" + i;
lblDayz.Anchor = AnchorStyles.None;
lblDayz.TextAlign = ContentAlignment.MiddleCenter;
lblDayz.Click += lblDayz_Click;
}
Event handler looks like:
public void lblDayz_Click(object sender, EventArgs e)
{
lblDayz.BackColor = Color.FromArgb(176, 180, 43);
lblDayz.ForeColor = Color.White;
}
Your current implementation is trying to change the properties of lblDayz, which might be a single label somewhere. But the way you're creating labels you have a number of labels generated in code. One for each day
That means you need your handler to react to the label that was clicked. The label that was clicked is the sender in your event handler. Crudely then you could handle it like this
public void lblDayz_Click(object sender, EventArgs e)
{
Label clickedLabel = sender as Label;
clickedLabel.BackColor = Color.FromArgb(176, 180, 43);
clickedLabel.ForeColor = Color.White;
}

Removing dynamically generated buttons

I'm working with C# windows forms and need some help. I have a button that creates other buttons and adds them to the list 'buttons'. I need to have each button created destroy itself when it is clicked.
//create new button
Button newButton = new Button();
newButton.Name = "aButt"+buttNum;
Debug.WriteLine(newButton.Name);
buttNum++;
newButton.Text = "Button!";
newButton.Height = 50;
newButton.Width = 50;
//controls where the new button gets placed
if (curX > 9)
{
curX = 0;
curY++;
//defines the point the button spawns
newButton.Location = new System.Drawing.Point((curX * 55)+10, curY * 55);
//increments X to avoid placing a button on top of another
curX++;
}
else
{
newButton.Location = new System.Drawing.Point((curX * 55) + 10, curY * 55);
curX++;
}
newButton.UseVisualStyleBackColor = true;
newButton.Click += new System.EventHandler(this.removeThisButton);
buttons.Add(newButton);
this.Controls.Add(newButton);
I have the event listener set up, but since the sender has no actual information on the button itself i'm not sure how to get rid of it.
Any help is appreciated!
The click event handler has the signature
private void myButton_Click(object sender, EventArgs e)
The object sender is the source of the event. Just cast that to a Button, and there's what got clicked:
Button whatWasClicked = sender as Button;
if(whatWasClicked == null)
// never mind -- it wasn't a button...
Sender is the button. You can remove it from Form's control collection like this:
private void removeThisButton(object sender, EventArgs e) {
this.Controls.Remove(sender);
}

Capture the right button click event

I'm playing around abit with winforms and its controls and just discovered how to do custommade buttonclicks. However, there is a problem. I've got a loop, that's looping through a list of elements, and if a condition appears - I'm creating a button that will pop up a gridview.
public void draw(ref Panel inputPanel) //draws the eventline
{
int stepCounter = 0;
for (int i = 0; i < DaysList.Count-1; i++)
{
Button b1;
if (DaysList[i].Elements.Count > max)
{
b1 = new Button(); //Create the box
b1.Width = 120;
b1.Height = 40; //Set width and height
b1.Location = new Point(stepCounter + 35, 70); //Location
inputPanel.Controls.Add(b1); //
b1.Text = "Check event date in grid";
b1.Show();
b1.BringToFront();
b1.Click += new EventHandler((sender, e) => btn_Click(sender, e, DaysList[i].Elements));
stepCounter += 200;
}
}
}
That was my method for creating the buttons and a click event for the when my condition appears. The function that is passed to the eventhandler looks like this:
public void btn_Click(object sender, EventArgs e, List<EventElement> inputElems)
{
Button button = sender as Button;
DataGridForm window = new DataGridForm(inputElems);
window.Show();
}
public class EventElement
{
public EventElement()
{
}
public int Count{get;set;}
public string Date{get;set;}
}
The clickpart of the event is fine but whenever i click the spawned buttons, I get the wrong data into the gridview. As an example: The loop has created four buttons for me and they are presented on a straight line on the form. But whenever i click one of the buttons - dosnt matter which one of them, the button always return the data of the last spawned button. A more clear example: lets say we have the list inputElems looks like this:
inputElems[0].Count -> 2644
inputElems[1].Count -> 2131
inputElems[2].Count -> 8467
inputElems[3].Count -> 5462
When i now click the second button, the input to the second buttons parameter list should have the values (sender, e, 2131), right? but for some reason, the last argument gets the same like the 4th element in the list, even though i call the secondly created button.
I figured that it has something to do with me always calling the last added button_click to the eventhandler of the button, if so, how do I call different clicks from the EventHandler?
Instead of passing inputElems with the EventHandler, you can use Tag.
E.g. use:
b1.Tag=i;
Then in your click event handler:
public void btn_Click(object sender, EventArgs e)
{
Button button = sender as Button;
DataGridForm window = new DataGridForm(DaysList[int.Parse(button.Tag.ToString())].Elements);
window.Show();
}
The problem is that the for loop is out of scope, and thus unable to provide you with the data you're looking for. A more straight forward approach might be something like this:
public void draw(ref Panel inputPanel) //draws the eventline
{
int stepCounter = 0;
for (int i = 0; i < DaysList.Count-1; i++)
{
Button b1;
if (DaysList[i].Elements.Count > max)
{
b1 = new Button(); //Create the box
b1.Width = 120;
b1.Height = 40; //Set width and height
b1.Location = new Point(stepCounter + 35, 70); //Location
inputPanel.Controls.Add(b1); //
b1.Text = "Check event date in grid";
b1.Show();
b1.BringToFront();
b1.Tag = DaysList[i].Elements;
b1.Click += btn_Click;
stepCounter += 200;
}
}
}
and then in btn_Click, do this:
public void btn_Click(object sender, EventArgs e)
{
Button button = sender as Button;
int inputElems = (List<EventElement>)button.Tag;
DataGridForm window = new DataGridForm(inputElems);
window.Show();
}

How to delete a button when another button is clicked?

It's probably quite trivial, but my problem is I need to delete two buttons when one of them is clicked. At the moment, my code will create these two buttons when a third is clicked. What I want is for one of these options to do something (this I have done) and, once complete, make these buttons disappear again. Here is the code to create two buttons:
private void btnRandom_Click(object sender, EventArgs e)
{
Button d = new Button();
Button c = new Button();
d.Text = "Dice";
c.Text = "Chance Card";
d.Name = "btnDice";
c.Name = "btnCC";
d.Location = new Point(btnRandom.Location.X, btnRandom.Location.Y + 30);
c.Location = new Point(btnRandom.Location.X, btnRandom.Location.Y + 60);
d.Click += new EventHandler(d_Click);
c.Click += new EventHandler(c_Click);
this.Controls.Add(d);
this.Controls.Add(c);
}
And below is my failed attempt at removing this button
private void d_Click(object sender, EventArgs e)
{
this.Controls.Remove(btnDice); // This doesnt work
}
I guess you code is OK, but you need to re-paint the form after removing the control.
this.Controls.Remove(btnDice);
this.Refresh();
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.refresh.aspx
You can disable the button using
this.btnDice.Enabled = false;
or you can use visible property to hide it
e.g.
this.btnDice.Visible = false;
For removing You might need to refresh the form.
Why don't you just make the button disappear and reappear again ?
//Make the button disappear
this.btnDice.Visible = false;
//Make the button reappear
this.btnDice.Visible = true;
you can try this by removing the sender :
private void d_Click(object sender, EventArgs e)
{
this.Controls.Remove((Button)(sender));
this.Refresh();
}

Function for click events

I want to implement Nine Men's Morris Game.
I have a board with 24 pictureboxes and on the left and right side, 9 red pictureboxes and 9 green pictureboxes.
I want to add them in a list:
List<PictureBox> ls = new List<PictureBox>();
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 1; i <= 24; i++)
{
PictureBox p = new PictureBox();
p.Name = "pictureBox" + i;
ls.Add(p);
}
}
is it ok?
and is it possible to do something like this: I want to click on one of the 24 pictureboxes, and make the background of that picturebox to become one time green and one time red?
I mean recursive function or something like that that can recognize when i click on a picturebox, search in the list for that picturebox and changes his backcolor?
You don't need any pictureBox list here.
for (int i = 1; i <= 24; i++)
{
PictureBox p = new PictureBox();
p.Click += p_Click;
//of course, somecontrol.Controls.Add(p);
//for ex: this.Controls.Add(p);
}
-
void p_Click(object sender, EventArgs e)
{
((PictureBox)sender).BackColor = Color.Green;
}
EDIT
It seems you are trying to add an event handler to all pictureBoxes
**parentControl**.Controls.OfType<PictureBox>()
.ToList().ForEach(p => p.Click+=p_Click);
I assume the list of 24 PictureBoxes is supposed to represent the points on a nine man morris board where the player's men can be positioned.
I4V is right that all you need to do is add a click handler to each picture box. If you want to have the background alternate between green and red, keep your original list, but add the click handler in it
for (int i = 1; i <= 24; i++)
{
PictureBox p = new PictureBox();
p.Name = "pictureBox" + i;
p.Click += p_Click; // <----------
ls.Add(p);
}
And modify i4v's click handler to use the current background color to determine the new background color.
void p_Click(object sender, EventArgs e)
{
PictureBox p = (PictureBox)sender);
p.BackColor = p.BackColor == Color.Green ? Color.Red : Color.Green;
}
A couple of other points.
You don't set an initial background color, so it will be the default color until clicked on, when it will be set to Green (as Green isn't the default background color).
Why name your pictureboxes w/ their List index + 1? Why not just use the List index and the natural C# iteration from 0: for (int i = 0; i < 24; i++)?
The method you have outlined would not work, however there is another way to do the same thing using the sender object passed into the event handler:
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 1; i <= 24; i++)
{
PictureBox p = new PictureBox();
p.Name = "pictureBox" + i;
p.Click += PictureBox_Click;
}
}
void PictureBox_Click(object sender, EventArgs e)
{
PictureBox event_picturebox = (PictureBox)sender;
event_picturebox.BackColor = Color.White;
}
You just have to map every picture box you want to run this event to the same event, the event will then be able to perform actions on this pictureBox because a reference to it was passed in.
If you already have the picture boxes defined in the form, you just need to do something like:
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.Click += PictureBox_Click;
pictureBox2.Click += PictureBox_Click;
// and keep going
// OR
// this is a bit dangerous if you don't want ALL
// your picture boxes to have this event
// also assumes that you know picturebox1 exists.
foreach (object f in this.Controls)
{
if (f.GetType().Equals(pictureBox1.GetType()))
{
((PictureBox)f).Click += button_Click;
}
}
}

Categories