How to delete a button when another button is clicked? - c#

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();
}

Related

C# - How to find out which dynamic button was clicked?

I am writing a program where I dynamically add buttons, I do that by storing them in a Dictionary to get a certain value from them later on (the color of the background).
I need to set a Click event on every one of them, but every Click event has to be a little different, as by clicking the button, a ColorDialog pops up and changes the background of the button.
Is there a way to know which button I clicked? In the following code, the button1 click event adds the other buttons and sets the EventHandler for each of them, what should be the code for the EventHandler? Thank you so much in advance guys.
int i = 0;
Dictionary<int, Button> buttonDictionary = new Dictionary<int, Button>();
Dictionary<int, ColorDialog> colorsDictionary = new Dictionary<int ColorDialog>();
public void button1_Click(object sender, EventArgs e)
{
i++;
buttonDictionary.Add(i, new Button());
buttonDictionary[i].Click += new EventHandler(Click);
this.Controls.Add(buttonDictionary[i]);
}
public void Click(object sender, EventArgs e)
{
//Somehow get the int key of the button that was clicked???? (in this case: int j)
int j;
if (!colorsDictionary.ContainsKey(j))
{
colorsDictionary.Add(j, new ColorDialog());
}
if (colorsDictionary[j].ShowDialog() == DialogResult.OK)
{
buttonDictionary[j].BackColor = colorsDictionary[j].Color;
}
}
The code is made just for adding the buttons, I will be glad for any kind of help, thank you guys!
Well, a direct answer to your question is: cast the sender to a Button
Button pressedButton = (Button) sender;
and then check to which button of the dictionary it matches:
foreach (var entry in buttonDictionary)
{
if (entry.Value == pressedButton)
{
j = entry.Key;
break;
}
}
However, that's overly complex for what you want to achieve. It would be much easier if you had a direct relationship between the button and the color picker:
Dictionary<Button, ColorDialog> buttonDictionary = new Dictionary<Button, ColorDialog>();
Then fill it like this:
public void button1_Click(object sender, EventArgs e)
{
i++;
var button = new Button();
this.Controls.Add(button);
button.Click += new EventHandler(Click);
buttonDictionary.Add(button, null);
}
And later access it with
public void Click(object sender, EventArgs e)
{
Button pressedButton = (Button) sender;
ColorDialog dialog = buttonDictionary[pressedButton];
if (dialog == null)
{
dialog = new ColorDialog();
buttonDictionary[pressedButton] = dialog;
}
if (dialog.ShowDialog() == DialogResult.OK)
{
pressedButton.BackColor = dialog.Color;
}
}
Even more, the question is why you would need so many ColorDialgos, since it should be possible with one dialog only. You can get rid of i, j, all dictionaries and most handling as well. IMHO, the following should be sufficient:
public void button1_Click(object sender, EventArgs e)
{
var button = new Button();
Controls.Add(button);
button.Click += Click;
}
public void Click(object sender, EventArgs e)
{
Button pressedButton = (Button) sender;
ColorDialog dialog = new ColorDialog {Color = pressedButton.BackColor};
if (dialog.ShowDialog() == DialogResult.OK)
{
pressedButton.BackColor = dialog.Color;
}
}
Bonus info:
I don't exactly know what you want to achieve. But your buttons will all be in the same place, overlapping each other. To avoid this, drag a flow layout panel onto the form and then add the buttons to the flow layout:
flowLayoutPanel1.Controls.Add(button);
This will ensure that your buttons are nicely arranged.

How to use dynamic button click event handler without using page init or page load

I am trying to figure out how to use a click event handler for my 4 buttons that I have generated dynamically without putting any code in page init or oninit. I have one button that once clicked it generates 4 more buttons. The click event handler for these 4 buttons is not working. Here is the code. Has anybody figured out a way to use the click events in asp.net c# without first putting it in page_load? If I can solve this problem, I can solve my real problem in a bigger scenario.:
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 4; i++)
{
Button b = new Button();
b.ID = i.ToString();
b.Text = "ClickMe";
b.Visible = true;
b.Click += new EventHandler(b_click);
PlaceHolder1.Controls.Add(b);
}
}
void b_click(object sender,EventArgs e)
{
Label1.Text = "ok";
}
Make sure the ID of your dynamic controls include a distinct keyword. In my example below I prepended "DYNAMIC_" to their ID. Then override OnPreRender() like this:
protected override void OnPreRender(EventArgs e)
{
if (Page.IsPostBack && !IsPostBackEventControlRegistered)
{
var controlName = this.Request.Form.AllKeys.SingleOrDefault(key => key.Contains("DYNAMIC_"));
processEventForDynamicControl(controlName);
}
base.OnPreRender(e);
}
private void processEventForDynamicControl(string controlName)
{
//Do your dynamic button click processing here
}
Of course, if your dynamic controls use doPost() (which sadly Button doesn't) you can retrieve the control directly from __EVENTTARGET like this:
var controlName = Request.Params.Get("__EVENTTARGET")
You want to load controls inside Page_Load. Otherwise, they are not in control tree, and they won't be able to trigger b_click event.
public int Counter
{
get { return (int?) ViewState["Counter"] ?? 0; }
set { ViewState["Counter"] = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
var counter = Counter;
for (int i = 0; i < counter; i++)
{
Button b = new Button();
b.ID = i.ToString();
b.Text = "ClickMe";
b.Visible = true;
b.Click += b_click;
PlaceHolder1.Controls.Add(b);
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Counter = 4;
for (int i = 0; i < 4; i++)
{
Button b = new Button();
b.ID = i.ToString();
b.Text = "ClickMe";
b.Visible = true;
b.Click += b_click;
PlaceHolder1.Controls.Add(b);
}
}
void b_click(object sender, EventArgs e)
{
Label1.Text = "ok";
}
Note: If you plan to load inside Page_Init, you want to use Session instead of ViewState.
Basically I got it working.There is no way around it. You have to use Oninit or Page_load and put your b.Click += new EventHandler(b_click) code there in addition to the PlaceHolder1.Controls.Add(b); there as well,for the event handler to register properly with the button. The problem with this method is that it places the button on top of the PlaceHolder portion of the web page which is not what I want. I want to beable to place the button at a particular position in the web page. So how do you go around doing this? Basically after the PlaceHolder1.Controls.Add(b) simply make the button invisible. Then in the when you are ready to place the button in a particular part of your html call PlaceHolder1.Controls.Add(b) again and make it visible. That works for me. If anyone needs help with this I can post some sample code and you can test it for yourself. Thanks all.

How to know what Linklabel has been clicked?

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;
}

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);
}

How can i take dynamically created buttons' name when they are clicked?

I'm making a mahjong game and I'm totally new at C#, I wonder how i can take a button's name when it's clicked. All the buttons are created dynamically in the form.
public Button createButton(node x)
{
Button nButton;
nButton = new Button();
nButton.Name = x.info.ToString();
nButton.Text = x.info.ToString();
nButton.Width = 55;
nButton.Height = 75;
nButton.Visible = true;
if (x.isValid())
nButton.Enabled = true;
else
nButton.Enabled = false;
nButton.Click += new System.EventHandler(n1_click);
return nButton;
}
in the form i take buttons with this code
myButton = createButton(tp);
myButton.Location = new System.Drawing.Point(25 , 25);
this.Controls.Add(myButton);
The first argument to the event handler is the sender, you can cast that to a Button and then access the Name property.
Here is a small example of the event handler.
private void Button_Click(object sender, EventArgs e)
{
Button button = sender as Button;
if (button != null)
{
// Do something with button.Name
}
}
Edit: As Hans mentioned in the comments, using as could hide a potential bug. Using the as operator as in the example above will ensure that if you inadvertently wire this handler to an event of another control the code will handle it graciously and not throw an InvalidCastException, but there-in lies a problem as well, because this now silently fails you might not pickup a bug in your code. If the exception was thrown you would have realized there is a problem and been able to track it down. So the updated code would be something like this.
private void Button_Click(object sender, EventArgs e)
{
// If sender is not a Button this will raise an exception
Button button = (Button)sender;
// Do something with button.Name
}
With the following code you can get the button that was clicked
protected void Button1_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
}
on the function which handles the click "n1_click"
private void n1_click(object sender, EventArgs e)
{
Button temp = (Button)sender;
string neededText = temp.Text;
}

Categories