Second Run of same Method Fail - c#

Im calling method StartNewGame by clicking menu item and everything works fine until i click menu item again and yes i want it repeatable, i must have missed something :(
public Panel Gamepanel;
public TextBox Nazwagracza;
private void startNewToolStripMenuItem_Click(object sender, EventArgs e)
{
StartNewGame();
}
void CreateNazwagracza()
{
Nazwagracza = new TextBox();
Nazwagracza.Parent = Gamepanel;
Nazwagracza.MaxLength = 15;
Nazwagracza.Top = odstepgora;
Nazwagracza.Width = 100;
Nazwagracza.Height = 25;
Nazwagracza.Left = Kalendarz.Left - Nazwagracza.Width - odsteplewo;
}
void StartNewGame()
{
CreateGamepanel();
CreateNazwagracza();
Nazwagracza.Text = "Raz";
}
int odstepgora = 10;
int odsteplewo = 10;
void CreateGamepanel()
{
Gamepanel = new Panel();
Gamepanel.Top = odstepgora;
Gamepanel.Left = odsteplewo;
Gamepanel.Width = bgimage.Width - 20;
Gamepanel.Height = bgimage.Height - 40;
Gamepanel.BackColor = Color.Transparent;
Gamepanel.ForeColor = Color.Gray;
Gamepanel.Visible = true;
Gamepanel.BorderStyle = BorderStyle.Fixed3D;
Gamepanel.Parent = bgimage;
}
Maybe i should rewrite/clear all panel each time i call StartNewGame? what would be best way to do that? Any advices on improving above also welcome.
Thanks in advance.
Edited: Example what is not working is once set Text "Raz" in Nazwagracza.Text and said changed by user and then when u call StartNewGame again the Text Value dont change - strange.

Related

C# how to make function for all buttons using object sender

I´m using WindowsForm and working with flat design. In the program there are 6 buttons, these buttons are made of a label and a panel. The label controls all the actions that the button can do. when i started writing the program i made one function for each button, now i like to use one function that controls all buttons. I have tried to make that work but I´m stuck and can´t find a way to solve it.
Been looking around at the forum for solutions but i think that i might not know what i´m looking for.
This is what i made so far.
Buttons[] cobra = new Buttons[5];
private class Buttons
{
private bool position;
private string name;
public bool Position
{
get { return position; }
set { position = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
}
private void SetButtons()
{
cobra[0].Name = "label3";
cobra[0].Position = false;
cobra[1].Name = "label4";
cobra[1].Position = false;
}
private void CheckStatusButtons(object import)
{
for (int i = 0; i < cobra.Length; i++)
{
}
}
private class ToggelFunction
{
private bool hawk;
public bool Hawk
{
get { return hawk; }
set { hawk = value; }
}
}
ToggelFunction tiger = new ToggelFunction();
private void label3_Click(object sender, EventArgs e)
{
if (tiger.Hawk == false)
{
button1.BackColor = Color.PaleGreen;
label3.Text = "ON";
if (myport.IsOpen)
{
send(new byte[] { 16, 128, 32, 16, 1 });
}
tiger.Hawk = true;
return;
}
if (tiger.Hawk == true)
{
button1.BackColor = Color.DarkSeaGreen;
label3.Text = "2";
if (myport.IsOpen)
{
send(new byte[] { 16, 128, 32, 8, 1 });
}
tiger.Hawk = false;
return;
}
}
"label3_Click" this is my function for button 1, all buttons look the same just different variables.
As I found on the forum, you can use object sender to i identify which button that made the click and from there use that in the function to make action.
So all buttons will use this functions, i´m not sure how to compare values in the if statement, if button 1 is click then it should check what values button 1 has.
My idea was to make a class "Buttons" and an array to store all the values of each button, it´s not completed yet. When a button is clicked it checks
with the array what values that button has and compare that in the function depending on what the action is. The first action would be to check if the button is on or off. If it´s off then it enters that if statement and there some actions will happen, change of color and the text, these values also have to be stored in the array i guess.
I have tried to compare the array with object sender, but i get some error saying that you can´t compare bool with object i think.
So i wonder if some one might have a solution or suggestions?
I have made a simple example of what i think you want to do. bare in mind this does not abide by all coding best practises but its not a mess either. You will need to put your safety null checks in.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public class ButtonVariables
{
public int value1 { get; set; }
public int value2 { get; set; }
}
Dictionary<string, ButtonVariables> bv = new Dictionary<string, ButtonVariables>();
private void ProcessClick(object sender, EventArgs e)
{
ButtonVariables vars = GetVariables(sender);
//Do stuff with your variable set here
}
private ButtonVariables GetVariables(object sender)
{
ButtonVariables returnValue = new ButtonVariables();
switch (((Button)sender).Name.ToLower())
{
case "buttona":
return bv["A"];
case "buttonb":
return bv["B"];
case "buttonc":
return bv["C"];
default:
break;
}
return null;
}
private void ButtonA_Click(object sender, EventArgs e)
{
ProcessClick(sender, e);
}
private void ButtonB_Click(object sender, EventArgs e)
{
ProcessClick(sender, e);
}
private void ButtonC_Click(object sender, EventArgs e)
{
ProcessClick(sender, e);
}
}
I've basically added two methods to handle your method. One to identify the button and get its related values from a dictionary that you will have to populate with your Buttons class. and one to carry out the logic.
EDIT
As requested in the comments here's an easy (but not the only way) to point your event listeners towards the same method.
Initially you need to set up with one button and double click it or do some other way to create the forms Button_Click() Event Method. At this point an event listener delegate has been added to your Form.Designer.cs File. Open that file and you will see something like this:
//
// ButtonA
//
this.ButtonA.Location = new System.Drawing.Point(12, 12);
this.ButtonA.Name = "ButtonA";
this.ButtonA.Size = new System.Drawing.Size(75, 23);
this.ButtonA.TabIndex = 0;
this.ButtonA.Text = "button1";
this.ButtonA.UseVisualStyleBackColor = true;
this.ButtonA.Click += new System.EventHandler(this.ButtonA_Click);
What you need to do is create your other buttons and add this code in for them with a change to the last line new System.EventHandler(this.ButtonA_Click); This line basically states which method to call when the ButtonA.Click event is invoked. At this point you can add what ever method you want (as long as you name is nicely for good convention). So your example would be this :
//
// ButtonA
//
this.ButtonA.Location = new System.Drawing.Point(12, 12);
this.ButtonA.Name = "ButtonA";
this.ButtonA.Size = new System.Drawing.Size(75, 23);
this.ButtonA.TabIndex = 0;
this.ButtonA.Text = "button1";
this.ButtonA.UseVisualStyleBackColor = true;
this.ButtonA.Click += new System.EventHandler(this.ProcessClick);
//
// ButtonB
//
this.ButtonB.Location = new System.Drawing.Point(12, 12);
this.ButtonB.Name = "ButtonB";
this.ButtonB.Size = new System.Drawing.Size(75, 23);
this.ButtonB.TabIndex = 0;
this.ButtonB.Text = "B";
this.ButtonB.UseVisualStyleBackColor = true;
this.ButtonB.Click += new System.EventHandler(this.ProcessClick);
//
// ButtonC
//
this.ButtonC.Location = new System.Drawing.Point(12, 12);
this.ButtonC.Name = "ButtonC";
this.ButtonC.Size = new System.Drawing.Size(75, 23);
this.ButtonC.TabIndex = 0;
this.ButtonC.Text = "C";
this.ButtonC.UseVisualStyleBackColor = true;
this.ButtonC.Click += new System.EventHandler(this.ProcessClick);
Remember you need to physically create the buttons on the form itself.
Lets say you have three labels and a panel for each label. You can add the event handler to all of them and whenever that event fires the event handler will use that label as the sender. To keep the panel associated with the label, you could add the panel to the label's tag property. Then, in the event handler you can then get the panel from the label.
label1.Click += label_Click;
label2.Click += label_Click;
label3.Click += label_Click;
label1.Tag = panel1;
label2.Tag = panel2;
label3.Tag = panel3;
In the event handler, just cast sender to Label and there you have your label object to do whatever you want with and like I said, the panel is in the Tag property. I did a little refactoring to your code to make it cleaner looking.
private void label_Click(object sender, EventArgs e)
{
// this is what itsme86 was suggesting in the comments
var label = (Label)sender;
var panel = (Panel)label.Tag;
label.BackColor = tiger.Hawk ? Color.DarkSeaGreen : Color.PaleGreen;
label.Text = tiger.Hawk ? "2" : "ON";
if (myport.IsOpen)
send(new byte[] { 16, 128, 32, 8, 1 });
tiger.Hawk = !tiger.Hawk;
}
Let me know if you have any questions about this.

How to hide all items in a private void method you've created?

so I created my own private void that can create buttons
private void addButtonsToForm()
{
for (int i = 0; i < 26; i++)
{
Button currentNewButton = new Button();
currentNewButton.Size = new Size(20, 30);
currentNewButton.Location = new Point(20 + 25 * i, 420);
currentNewButton.Text = ((char)(65 + i)).ToString();
currentNewButton.Click += LetterClicked;
letters[i] = currentNewButton;
this.Controls.Add(letters[i]);
}
}
The buttons are alphabets and will be accessed when the user wants to choose a letter ... but the problem is I'm trying to figure out how to go back when the user clicked or selected a button..
Originally I wanted to do was i could just hide all the buttons created and just make the previous button visible but for some reason it only hides the only button that is clicked
//this is under private void LetterClicked(object sender, EventArgs e)
Button selectedLetter = (Button)sender;
selectedLetter.Enabled = false;
i thought of stupid codes like
addbuttonstoform().visible = false; but of course that won't work.. but you might get an idea to where i want to go.... it's a bit confusing to explain... I'm new in c# and i'm creating a guess the word game so help could be great..
Here is a working solution for your problem. See below:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Alphabets
{
public partial class Form1 : Form
{
private Button[] _letters;
public Form1()
{
InitializeComponent();
AddButtonsToForm();
}
private void AddButtonsToForm()
{
_letters = new Button[26];
for (int i = 0; i < 26; i++)
{
Button currentNewButton = new Button
{
Name = "BtnLetter"+ ((char)(65 + i)),
Size = new Size(20, 30),
Location = new Point(20 + 25 * i, 420),
Text = ((char) (65 + i)).ToString()
};
currentNewButton.Click += LetterClicked;
_letters[i] = currentNewButton;
this.Controls.Add(_letters[i]);
}
}
private void LetterClicked(object sender, EventArgs e)
{
var selectedLetter = (Button) sender;
//hide all other buttons
foreach (var letter in _letters)
{
if (letter.Text != selectedLetter.Text)
{
var buttons = this.Controls.Find("BtnLetter" + letter.Text, true);
buttons[0].Enabled = false;
}
}
}
}
}

How to specify interaction beetween button click event handlers?

In the program, by clicking button2, is created a table and imlemented data insertion. Also created textbox and login button, which is used for reading data from this textbox. When the login button is pressed, next actions should happen:
MessageBox should display some text;
login.Text should be changed;
table, which was created by clicking button2 should be deleted.
I dont know actually how to get access from login.click event handler to table in button2. I guess it should be done somehow by using EventArgs, but i dont understand how. Also I thought about creating some variable outside button2 handler scope, and use it later, but I guess its a bad practise.
Please,tell me how to solve this, or maybe its just wrong decision to create windows forms components such a way? if it`s so, then how to?) here is my code:
private void button2_Click(object sender, EventArgs e)
{
label1.Hide();
label2.Hide();
textBox1.Hide();
textBox2.Hide();
button2.Hide();
int user_count = Int32.Parse(textBox2.Text);
int file_count = Int32.Parse(textBox1.Text);
DataGridView T = new DataGridView();
T.Dock = DockStyle.Top;
T.AutoResizeColumns();
T.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
T.ColumnCount = file_count + 1;
T.RowCount = user_count + 1;
Controls.Add(T);
Controller_cs c = new Controller_cs(user_count, file_count);
for(int i = 1; i < T.RowCount; i++)
{
T.Rows[i].Cells[0].Value = c.user_name_insertion(i-1);
}
for (int i = 1; i < T.ColumnCount; i++)
{
T.Rows[0].Cells[i].Value = c.file_name_insertion(i - 1);
}
for(int i = 1; i < T.RowCount;i++)
{
for(int j = 1; j < T.ColumnCount;j++)
{
T.Rows[i].Cells[j].Value = c.rigts_insertion(j-1,i-1);
}
}
Label l = new Label();
l.Text = "Name";
l.Left = 20;
l.Top = 180;
Controls.Add(l);
TextBox username = new TextBox();
username.Left = 20;
username.Top = 210;
Controls.Add(username);
Button login = new Button();
login.Text = "Enter";
login.Left = 130;
login.Top = 175;
login.Click += login_handler;
Controls.Add(login);
}
private void login_handler(object sender, EventArgs e)
{
Button b = (Button)sender;
if (b.Text == "Enter")
{
b.Text = "Exit";
MessageBox.Show("Enter is done");
}
else
{
b.Text = "Enter";
MessageBox.Show("Quit is done");
}
}

Which Design pattern for dynamical creating buttons

I have created a custom user control that adds combo boxes to itself.
My custom user control has 1 button which Adds Two Combo Boxes.
Clicking on it adds 2 combo boxes under the last two.
When the selected index is changed on any of the combo boxes it will run a calculation using the selected values in each box.
This is my code so far...
public partial class PlateSectionAdder : UserControl
{
private List<Dictionary<string, CueComboBox>> listOfTwoCombos = new List<Dictionary<string, CueComboBox>>();
public List<string> ColList { get; }
public List<string> PlateList { get; }
private int count = 1;
private int gap = 3;
private int edge = 5;
private Button btnAdd = new Button();
public PlateSectionAdder(List<string> collist, List<string> platelist)
{
InitializeComponent();
this.ColList = collist;
this.PlateList = platelist;
btnAdd.FlatStyle = FlatStyle.Flat;
btnAdd.Top = edge / 2;
btnAdd.Left = edge;
btnAdd.Width = this.Width - (edge * 2);
btnAdd.Click += BtnAdd_Click;
this.Controls.Add(btnAdd);
}
private void BtnAdd_Click(object sender, EventArgs e)
{
CueComboBox cmbCols = new CueComboBox();
cmbCols.DataSource = this.ColList;
cmbCols.Top = (btnAdd.Bottom + edge) * count;
cmbCols.Left = edge;
cmbCols.Width = btnAdd.Width / 2 - gap;
cmbCols.SelectedIndexChanged += CalculatePlateSections;
CueComboBox cmbPlates = new CueComboBox();
cmbPlates.DataSource = this.PlateList;
cmbPlates.Top = (btnAdd.Bottom + edge) * count;
cmbPlates.Left = cmbCols.Right + gap;
cmbPlates.Width = btnAdd.Width / 2 - gap;
cmbCols.DataSource = ColList;
this.Controls.Add(cmbCols);
this.Controls.Add(cmbPlates);
this.Height = btnAdd.Height + (cmbCols.Height * count) + edge + edge + 1;
cmbCols.DataSource = ColList;
cmbPlates.DataSource = PlateList;
cmbPlates.SelectedIndexChanged += CalculatePlateSections;
count++;
}
private void CalculatePlateSections(object sender, EventArgs e)
{
MessageBox.Show("Test");
}
The combo boxes seem to be copies of the same instance, rather than independent, I thought by using the new keyword they would be each there own instance.
I am sure there a design pattern out there that would be right for this but not sure which one.
Has a look at the builder pattern but it does not seem exactly what I am looking for.
if there is anything unclear about this let me know and I will clarify.

Array of buttons: change property

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.

Categories

Resources