I have multiple groupbox, which one contains a question and some answers and button ANSWER in each GroupBox. I create GroupBox and its Controls in Form_Load Method, not manually. How to handle button_click events for every button? I think it's not necessary to write this handle method for every button, because there are only two different button_handler: for questions where there can be only one correct answers, and for questions, where multiple answers can be correct.
My questions look like:
My GroupBox structure:
int loc = 20;
for (int i = 0; i < 10; i++)
{
GroupBox gb = new GroupBox();
gb.Name = "GroupBox" + (i + 1);
gb.Size = new Size(500, 200);
gb.Location = new Point(40, loc);
gb.BackColor = System.Drawing.Color.Aquamarine;
Label q_text = new Label(); // текст питання
q_text.Name = "label" + (i + 1);
q_text.Text = "Питання" + (i + 1);
q_text.Font = new Font("Aria", 10, FontStyle.Bold);
q_text.Location = new Point(10, 10);
gb.Controls.Add(q_text);
int iter = q_text.Location.Y + 30;
if (i <= 5)
{
foreach (string key in questions[i].answers.Keys)
{
RadioButton rb = new RadioButton();
rb.Text = key;
rb.Size = new Size(120, 25);
rb.Location = new Point(q_text.Location.X + 10, iter);
iter += 30;
gb.Controls.Add(rb);
}
}else
if (i > 5)
{
foreach (string key in questions[i].answers.Keys)
{
CheckBox rb = new CheckBox();
rb.Text = key;
rb.Size = new Size(120, 25);
rb.Location = new Point(q_text.Location.X + 10, iter);
iter += 30;
gb.Controls.Add(rb);
}
}
Button b = new Button();
b.Name = "button" + (i + 1);
b.Text = "Answer";
b.Location = new Point(gb.Size.Width - 120, gb.Size.Height - 30);
gb.Controls.Add(b);
this.Controls.Add(gb);
loc += 200;
}
You can create a general click event for your buttons:
Button b = new Button();
b.Name = "button" + (i + 1).ToString();
b.Click += b_Click;
and in the method, examine the sender to see which button was clicked:
void b_Click(object sender, EventArgs e) {
Button b = sender as Button;
if (b != null) {
GroupBox gp = b.Parent as GroupBox;
int bIndex = Convert.ToInt32(b.Name.Substring(6)) - 1;
MessageBox.Show(string.Format("I'm clicking {0}, question index #{1}",
gp.Name, bIndex));
}
}
After that, you would have to examine the checked values of your GroupBox child controls with the allowable answers in the questions[bIndex].answers variable.
Related
I have a button in the form. A groupbox is loaded each time the button is clicked (you can refer to my previous question). there are few textboxes and labels in each of the groupbox. I have raised key down events for the textboxes in the groupbox. The keyDown event does a few mathematical calculations.
Link to my previous question:
Loading multiple Groupboxes in the form using the button_click event
It works fine when only one groupbox is loaded. But when the second groupbox is loaded, the event raised doesnot work for the textboxes in the previously loaded groupboxes. It only works for the new groupbox.
What should be done to retain the events for the controls in the previous groupbox when the new group box is loaded.
This is the first thing I tried:
private GroupBox GetGroupBox(int a, int b, int c)
{
System.Windows.Forms.GroupBox gBox = new System.Windows.Forms.GroupBox();
Form1 myObj = new Form1();
gBox.Text = "S" + (a.ToString());
gBox.Name = "S" + (a.ToString());
gBox.Width = 150;
gBox.Height = 150;
gBox.Location = new Point(15 + (count - 1) * (gBox.Width + 10), 400);
// Labels
Label lb1 = new Label();
lb1.Text = "Length";
lb1.Width = 60;
lb1.Height = 20;
Label lb2 = new Label();
lb2.Text = "Angle";
lb2.Width = 50;
lb2.Height = 20;
// Textboxes
tbx1 = new TextBox();
tbx1.Name = "tbx" + b.ToString();
tbx1.Width = 40;
tbx1.Height = 10;
tbx1.Text = "50";
tbx1.KeyDown += Tbx1_KeyDown;
tbx2 = new TextBox();
tbx2.Name = "tbx" + c.ToString();
tbx2.Width = 40;
tbx2.Height = 10;
tbx2.Text = "45";
tbx2.KeyDown += Tbx2_KeyDown;
gBox.Controls.Add(lb1);
lb1.Location = new Point(10, 30);
gBox.Controls.Add(lb2);
lb2.Location = new Point(10, 70);
gBox.Controls.Add(tbx1);
tbx1.Location = new Point(100, 30);
gBox.Controls.Add(tbx2);
tbx2.Location = new Point(100, 70);
return gBox;
}
Then I tried creating an array of all the textboxes then used foreach loop to raise events:
TextBox[] tbxs = {tbx1, tbx2 };
foreach (TextBox tbx1 in tbxs)
{
tbx1.KeyDown += Tbx1_KeyDown1;
tbx2.KeyDown += Tbx2_KeyDown1;
}
But it didn't work out.
Case: I'm trying to create a few checkboxes which define what radiobutton is set by default. I don't have a clue how to approach this, to create the radiobuttons I'm using this xml:
<Lijsten>
<Lijst>
<Titel>Discipline</Titel>
<Waardes>Elektro</Waardes>
<Waardes>Mechanisch</Waardes>
<Waardes>Civiel</Waardes>
<Waardes>Proces</Waardes>
<Waardes>N.v.t.</Waardes>
</Lijst>
<Lijst>
<Titel>Discipline</Titel>
<Waardes>Elektro</Waardes>
<Waardes>Mechanisch</Waardes>
<Waardes>Civiel</Waardes>
<Waardes>Proces</Waardes>
<Waardes>N.v.t.</Waardes>
</Lijst>
<Lijst>
<Titel>Discipline</Titel>
<Waardes>Elektro</Waardes>
<Waardes>Mechanisch</Waardes>
<Waardes>Civiel</Waardes>
<Waardes>Proces</Waardes>
<Waardes>N.v.t.</Waardes>
</Lijst>
</Lijsten>
C# code:
foreach (XmlNode node in nodes)
{
int heightRadioButtons = 0;
WidthPanelsRow1 += 155;
Panel panel = new Panel();
panel.Size = new Size(140, 200);
panel.Location = new Point(WidthPanelsRow1, heightPanelsRow1);
panel.Name = "panel" + count.ToString();
panel.BackColor = Color.LightGray;
Label lbl = new Label();
lbl.Text = node["Titel"].InnerText;
lbl.Location = new Point(0, 0);
lbl.Font = font1;
panel.Controls.Add(lbl);
int counterLastRadioButton = 0;
XmlNodeList waardeNodes = node.SelectNodes("Waardes");
foreach (XmlNode wNode in waardeNodes)
{
counterLastRadioButton += 1;
heightRadioButtons += 20;
RadioButton rb = new RadioButton();
rb.Text = wNode.InnerText;
rb.Location = new Point(5, heightRadioButtons);
rb.Name = node["Titel"].InnerText;
if (waardeNodes.Count - 1 < counterLastRadioButton)
{
rb.Checked = true;
}
panel.Controls.Add(rb);
}
this.Controls.Add(panel);
}
What I'm trying to achieve: Create a checkbox dynamically from the xml, with per "Titel" the default "Waardes". So if I check that checkbox, the radiobutton of that "Titel" will change to that "value".
Im trying to create event with different index for dynamically created GroupBox. With my actual code event for every groupbox is that same. How can i make event with different index for every groupbox? My Code:
public void LoadGry()
{
// GroupBox groupbox = new GroupBox();
Label nazwagry = new Label();
for(int i = 0; i < myCollection.Count; i++)
{
GroupBox groupbox = new GroupBox();
groupbox.Text = myCollection[i];
groupbox.Size = new Size(290, 131);
groupbox.Location = new Point(6, 150 * (myCollection.Count - i - 1));
groupbox.ForeColor = Color.White;
Label label1 = new Label();
label1.Text = groupbox.Text;
label1.AutoSize = true;
label1.Location = new Point(groupbox.Location.X + 80, groupbox.Location.Y + 20);
groupbox.Controls.Add(label1);
Gry.Controls.Add(label1);
PictureBox picturebox = new PictureBox();
picturebox.Location = new Point(groupbox.Location.X + 5, groupbox.Location.Y + 20);
picturebox.Size = new Size(75, 75);
picturebox.SizeMode = PictureBoxSizeMode.StretchImage;
picturebox.LoadAsync(myCollection3[i]);
groupbox.Click += new EventHandler(delegate {groupboxclick(groupbox, picturebox, i);});
Label label2 = new Label();
label2.Text = "Status: " + "Aktualny";
label2.ForeColor = Color.Green;
label2.AutoSize = true;
label2.Location = new Point(label1.Location.X, label1.Location.Y + 20);
Gry.Controls.Add(label2);
Label zapiszopis = new Label();
zapiszopis.Text = myCollection4[i];
zapiszopis.Visible = false;
Gry.Controls.Add((Control)groupbox);
//MessageBox.Show("pokaz mi wysokosc");
}
}
private void groupboxclick(GroupBox groupbox, PictureBox picturebox, int itest)
{
groupbox.ForeColor = Color.Aqua;
this.pictureBox1.BackgroundImage = picturebox.BackgroundImage;
opishacka.Text = myCollection4[itest];
}
The problem is that the event setup is using the variable K value. For use the number instead you probably needs to create an expression manually to use the current value in each case.
BUT
You can easily do what you want using the following properties to attach values to controls.
1-) Tag in WinForms & WPF:
// Setup
pictureBox.Tag = i;
// Event
int i = (int) pictureBox.Tag;
2-) ViewState in WebForms
// Setup
ViewState[pictureBox.UniqueID] = i;
// Event
int i = (int) ViewState[pictureBox.UniqueID];
You can use many other techniques. I only post one for each popular framework. I guest that you are in a WinFors project.
Hope this help!
I have a test, and in Form1_Load I fill up this test with questions and answers. But it shows only first question. What's the matter?
int loc = 20;
for (int i = 0; i < 5; i++)
{
GroupBox gb = new GroupBox();
gb.Size = new Size(500, 200);
gb.Location = new Point(40, loc);
gb.BackColor = System.Drawing.Color.Aquamarine;
Label q_text = new Label(); // текст питання
q_text.Text = "Питання" + (i + 1);
q_text.Font = new Font("Aria", 10, FontStyle.Bold);
q_text.Location = new Point(gb.Location.X, gb.Location.Y);
gb.Controls.Add(q_text);
int iter = q_text.Location.Y + 30;
foreach (string key in questions[i].answers.Keys)
{
RadioButton rb = new RadioButton();
rb.Text = key;
rb.Size = new Size(120, 25);
rb.Location = new Point(q_text.Location.X + 10, iter);
iter += 30;
gb.Controls.Add(rb);
}
this.Controls.Add(gb);
loc += 300;
}
After examining your code, there are a few possible issues stemming from q_text
int loc = 20;
for (int i = 0; i < 5; i++)
{
GroupBox gb = new GroupBox();
gb.Size = new Size(500, 200);
gb.Location = new Point(40, loc);
gb.BackColor = System.Drawing.Color.Aquamarine;
Label q_text = new Label(); // текст питання
q_text.Text = "Питання" + (i + 1);
q_text.Font = new Font("Aria", 10, FontStyle.Bold);
q_text.Location = new Point(0, 0);
gb.Controls.Add(q_text);
int iter = q_text.Location.Y + 30;
foreach (string key in questions[i].answers.Keys)
{
RadioButton rb = new RadioButton();
rb.Text = key;
rb.Size = new Size(120, 25);
rb.Location = new Point(q_text.Location.X + 10, iter);
iter += 30;
gb.Controls.Add(rb);
}
this.Controls.Add(gb);
loc += 300;
}
The only changes here are q_text getting set to 0,0.
An additional change I would make however is to adjust hight by q_text's height:
int iter = q_text.Location.Y + q_text_Size.Height + 5;
Just in case the label was long and wrapped text.
I am adding two controls dynamically during runtime, however only the control that is made first is displayed.
Here is the code:
Label tempLab = new Label();
tempLab.text = "Test Label";
MyControl.Controls.Add(tempLab);
tempLab.Location = new Point(5,5);
Button tempBut = newButton()
tempBut.text = "Test Button";
MyControl.Controls.Add(tempBut);
tempBut.Location = new Point(20,20);
Isn't copypasta so ignore syntax errors with caps.
Any ideas ?
They are being added to a groupbox. I have tried adding them to a panel or just the form and the same issue occurs. I don't need event handlers, so please don't cite that requirement.
I quickly tried your code pasting it in a windows form constructor. It runs ok, but the label is slightly overlapping the button because of its size. You may want to autosize it:
Label tempLab = new Label();
tempLab.Text = "Test Label";
tempLab.AutoSize = true;
Controls.Add(tempLab);
tempLab.Location = new Point(5,5);
Button tempBut = new Button();
tempBut.Text = "Test Button";
Controls.Add(tempBut);
tempBut.Location = new Point(20,20);
Oh, by the way. You mentioned you are using MyControl as a Panel or a GroupBox. Please ensure that you are also adding MyControl to your Controls collection.
it appears that the location does not have a Size which becomes a flat line so to speak which is not visible.. this tempBut.Location = new Point(20,20); try changing to this
this.tempBut.Location = new System.Drawing.Point(20,20);
this.tempBut.Size = new System.Drawing.Size(30, 15);
hope this helps. I am adding a array of MyTextBox into panel.
Point prevlocation = new Point(0,0);
foreach (object key in keys) //List of Objects or which make new controls
{
MyTextBoxControlArray[i] = new MyTextBoxUserControl(key); //User control but could be any control like textbox etc
MyTextBoxControlArray[i].Width = this.panel1.Width - 50;
MyTextBoxControlArray[i].AutoSize = true;
MyTextBoxControlArray[i].InfoLoad += new MyTextBoxUserControl.InfoLoadEventHandler(Form1_InfoLoad);
if (i == 0)
{
//first control
prevlocation.Y += 3;
prevlocation.X += 3;
MyTextBoxControlArray[i].Location = prevlocation;
}
else
{
//adjsuting height and width
MyTextBoxControlArray[i].Location = new System.Drawing.Point(
prevlocation.X,
prevlocation.Y + MyTextBoxControlArray[i].Height+3);
}
prevlocation = MyTextBoxControlArray[i].Location;
i++;
}
this.panel1.Controls.AddRange(MyTextBoxControlArray); //in panel i can add a array of controls , but this could be done one by one
string sql3 = "SELECT COUNT(*) from systeminfo";//counting no of element
n = dm.countelement(sql3);
int i, c = 1;
int m = 100;
for (i = 0; i < n; i++, c++)
{
sql3 = " SELECT Company_name FROM systeminfo LIMIT " + (i + 1) + " OFFSET " + i + "";
string cname = dm.getlang(sql3);
PictureBox pb = new PictureBox();
Label lb = new Label();
pb.Location = new System.Drawing.Point(m, 30 + (30 * i));
lb.Location = new System.Drawing.Point(m-30, 30 + ((30 * i)-30));
pb.Name = "p" + c;
lb.Name = "l" + c;
lb.Size = new System.Drawing.Size(100, 20);
pb.Size = new System.Drawing.Size(30, 30);
lb.Text = cname;
lb.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
lb.BackColor = Color.Transparent;
pb.ImageLocation = #"..\image\image.jpg";
pb.MouseDown += new System.Windows.Forms.MouseEventHandler(this.picmap1_MouseDown_1);
pb.MouseMove += new System.Windows.Forms.MouseEventHandler(this.picmap1_MouseMove_1);
pb.MouseUp += new System.Windows.Forms.MouseEventHandler(this.picmap1_MouseUp_1);
picmap1.Controls.Add(pb);
picmap1.Controls.Add(lb);
c++;
}
private void picmap1_MouseMove_1(object sender, MouseEventArgs e)
{
var c = sender as PictureBox;
if (!_dragging || null == c) return;
c.Top = e.Y + c.Top - _yPos;
c.Left = e.X + c.Left - _xPos;
foreach (Control d in picmap1.Controls)
if (d is Label)
{
d.Top = e.Y + d.Top - _yPos;
d.Left = e.X + d.Left - _xPos;
}
}
private void picmap1_MouseUp_1(object sender, MouseEventArgs e)
{
var c = sender as PictureBox;
if (null == c) return;
_dragging = false;
}
private void picmap1_MouseDown_1(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
_dragging = true;
_xPos = e.X;
_yPos = e.Y;
foreach (Control d in picmap1.Controls)
if (d is Label)
{
_xPos = e.X;
_yPos = e.Y;
}
}
this is example of dynamic add control with move on mouse drag