How to check if dynamic checkbox are checked - c#

I've an application to import some pictures from a folder into another. I use picturebox to show my pictures and have a checkbox next to it. If it's unchecked i dont wanna import them.
So here is my code for creating a checkbox :
public void CreateCheckBox(Form formInstance,int yLocation, int xLocation, int iNumber)
{
CheckBox box = new CheckBox();
box.Name = "cbxName" + iNumber.ToString();
box.Location = new Point(xLocation+40,yLocation+90);
box.Visible = true;
box.Enabled = true;
box.Checked = true;
box.CheckedChanged += new EventHandler(cbx_CheckedChange);
formInstance.Controls.Add(box);
}
And my pictureBox :
public void CreatePictureBox(Form formInstance,int iNumber)
{
string[] tNomImage = RecupererNomImage();
PictureBox pbxImage = new PictureBox();
pbxImage.Name = "pbxName" + iNumber.ToString();
pbxImage.Image = Image.FromFile(tNomImage[iNumber]);
pbxImage.Width = 90;
pbxImage.Height = 90;
pbxImage.Location = new Point(iXLocation, iYLocation);
pbxImage.Visible = true;
pbxImage.BorderStyle = BorderStyle.FixedSingle;
pbxImage.SizeMode = PictureBoxSizeMode.Zoom;
formInstance.Controls.Add(pbxImage);
pbxImage.Enabled = false;
CreateCheckBox(this, iYLocation, iXLocation, iNumber);
if (iXLocation+iXSpacing*2 > this.Width)
{
iXLocation = XLOCATION;
iYLocation += iXSpacing;
}
else
{
iXLocation += iXSpacing;
}
And I wanna know which checkbox is checked so I can export the picture next to it.

I presume a picturebox will have a name like:
pbxName141
And its matching checkbox will have a name like:
cbxName141
You can ask the form for all the checked boxes:
var cbs = formInstance.Controls.OfType<CheckBox>().Where(cb => cb.Checked);
You can convert the checkbox name into the related picturebox name and look up the picturebox by name:
foreach(var cb in cbs){
var pbName = "p" + cb.Name.Substring(1);
var pb = formInstance.Controls[pbName];
}
So many ways to skin this cat..

Change your methods so that they RETURN the control that was created:
public CheckBox CreateCheckBox(Form formInstance,int yLocation, int xLocation, int iNumber)
{
// ... existing code ...
return box;
}
Now you can store a reference to that CheckBox in the Tag() property of the PictureBox:
public PictureBox CreatePictureBox(Form formInstance,int iNumber)
{
// ... existing code ...
CheckBox cb = CreateCheckBox(this, iYLocation, iXLocation, iNumber);
pbxImage.Tag = cb;
// ... existing code ...
return pbxImage;
}
Finally, add all of those returned PictureBoxes to a List<PictureBox> so you can easily reference and iterate over them. Simply cast the control stored in the Tag() property back to a CheckBox and you can determine if each PictureBox should be imported or not.

List<CheckBox> c = Controls.OfType<CheckBox>().Cast<CheckBox>().ToList();
forech(CheckBox item in c){
if(c.checked){
}
}

Related

Programmatically handle a dynamic range of C# UI form elements

I want to optimize my C# code for dynamically showing 1 to 10 elements in a form. The way I currently have it implemented is clumpsy and not very maintenance-friendly, so I did hope it will be possible to rewrite this, to a function that can handle e.g. one element at a time.
I have this below UI form which consists of 10 textBox and 10 pictureBox:
Depending on a showElements number I have, then it should show 1 to 10 of these boxes (both the textbox and the imagebox). My current code is this:
// How many boxes to show
int showElements = 4;
// Show X elements
for (int i = 1; i <= showElements; i++)
{
// Show specific element
switch (i)
{
case 1:
textBox1.Width = width - widthSubstract;
pictureBox1.Width = width - widthSubstract;
break;
case 2:
textBox2.Width = width - widthSubstract;
pictureBox2.Width = width - widthSubstract;
break;
... CUT but similar code up to 10
// Hide remaining elements
for (int i = showlements; i <= 10; i++)
switch (i)
{
case 1:
textBox1.Visible = false;
pictureBox1.Visible = false;
break;
case 2:
textBox2.Visible = false;
pictureBox2.Visible = false;
break;
... CUT but similar code up to 10
.. you get the trivial point for the rest. I have more code in each case but they all relate to the specific textBox or imageBox that should be shown.
I cannot figure out how I can optimize this? :-)
You can add UI elements on demand, instead of pre-defining them within your application.
for(int i = 0; i < 10; i++)
{
TextBox textBox = new TextBox();
textBox.Text = "Hello";
textBox.Tag = i;
this.Controls.Add(textBox);
}
Then re-access them via the Control property.
(this.Controls[i] as TextBox).Text += " World!";
In your particular case, you could define a custom control, containing a textBox and a PictureBox. Then adding that custom control as a child.
I do it like this :
namespace WindowsFormsApplication72
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
PictureText[] pictureTexts = new PictureText[] {
new PictureText { textbox = textBox1, picturebox = pictureBox1},
new PictureText { textbox = textBox2, picturebox = pictureBox2},
new PictureText { textbox = textBox3, picturebox = pictureBox3},
new PictureText { textbox = textBox4, picturebox = pictureBox4},
new PictureText { textbox = textBox5, picturebox = pictureBox5},
new PictureText { textbox = textBox6, picturebox = pictureBox6},
new PictureText { textbox = textBox7, picturebox = pictureBox7},
new PictureText { textbox = textBox8, picturebox = pictureBox8},
new PictureText { textbox = textBox9, picturebox = pictureBox9},
new PictureText { textbox = textBox10, picturebox = pictureBox10}
};
}
}
public class PictureText
{
public TextBox textbox { get; set; }
public PictureBox picturebox { get; set; }
}

How to display tool tip over a transparent image placed on a Winform button

I am displaying a transparent icon (32x32) of a red triangle in the upper right of a button control that signifies an error exists. Additionally, when the user hovers over the icon, a tool tip is displayed.
I have been able to display the icon and the associated tool tip. The problem is a transparent 32x32 icon with the red triangle being only 12x12. The tool tip should only trigger when hovering over the red triangle and not the transparent space.
Attempts have been made to display the triangle as a button as well as a picture box, however the tool tip still triggers in the transparent space. Additionally, the error provider was first used as a goal of what I am trying to accomplish.
UI items:
Button control: "btnAttachments"
Error Provider control: "errManager"
public class StackTest
{
private static Dictionary<string, Control> _errorMessages = new Dictionary<string, Control>();
public StackTest()
{
InitializeComponent();
InitErrors();
}
private void InitErrors()
{
_errorMessages.Clear();
AddErrorControl(btnAttachments, "Missing file attachment(s).");
//errManager.SetError(btnAttachments, "Missing file attachment(s)."); errManager.SetIconPadding(btnAttachments, -32);
}
private void AddErrorControl(Control control, string message = null, Enum selectedImage = null, EventHandler handler = null)
{
string name = "errFor" + control.Name;
if (_errorMessages.ContainsKey(name)) { return; }
Button errorIcon = CreateErrorControl(name, control);
errorIcon.BackgroundImage = Theme.GetImage(selectedImage ?? eImages_OtherIcons.Error_TopRight_Small);
//PictureBox errorIcon = CreateErrorControl2(name);
//errorIcon.Image = Theme.GetImage(selectedImage ?? eImages_OtherIcons.Error_TopRight_Small);
//errorIcon.Image = Bitmap.FromHicon((Theme.GetIcon(selectedImage ?? eImages_OtherIcons.Error_TopRight_Small)).Handle);
if (null != handler) { errorIcon.Click += handler; }
new ToolTip().SetToolTip(errorIcon, message);
errorIcon.Tag = message;
control.Controls.Add(errorIcon);
control.Controls[name].Location = new Point(control.Width - errorIcon.Width +20 , 0 );
_errorMessages.Add(name, errorIcon);
}
private Button CreateErrorControl(string name, Control control)
{
var errorIcon = new Button();
errorIcon.Name = name;
errorIcon.Size = new Size(32, 32);
//errorIcon.Location = new Point(control.Width - errorIcon.Width, 0);
errorIcon.Cursor = Cursors.Hand;
errorIcon.FlatStyle = FlatStyle.Flat;
errorIcon.BackColor = Color.Fuchsia;
errorIcon.FlatAppearance.MouseDownBackColor = Color.Transparent;
errorIcon.FlatAppearance.MouseOverBackColor = Color.Transparent;
errorIcon.FlatAppearance.BorderSize = 0;
errorIcon.Visible = false;
return errorIcon;
}
private PictureBox CreateErrorControl2(string name)
{
var errorIcon = new PictureBox();
errorIcon.Name = name;
errorIcon.Size = new Size(32, 32);
errorIcon.Cursor = Cursors.Hand;
errorIcon.BackColor = Color.Transparent;
errorIcon.Visible = false;
return errorIcon;
}
}
The built in Error Provider control achieves the desire results that I would like to replicate. Doing so will allow for a more robust application with more custom functionality then what the error provider offers.
Based on the GetPixel suggestion from #TaW, I did further R&D and now have something functional. The Tag of the picture box contains the tool tip message to be displayed. With the picture box being the "sender" of the mouse move, it was easy to extract the image back to a bitmap.
Thanks to all for the feedback.
First, I switched the testing to use CreateErrorControl2 with the PictureBox and added in a MouseMove.
private PictureBox CreateErrorControl2(string name) //, Control control)
{
var errorIcon = new PictureBox();
errorIcon.Name = name;
errorIcon.Size = new Size(32, 32);
errorIcon.Cursor = Cursors.Default;
errorIcon.BackColor = Color.Transparent;
errorIcon.Visible = false;
errorIcon.MouseMove += new MouseEventHandler(DisplayToolTip);
return errorIcon;
}
The following code was also added in support of the DisplayToolTip method.
private bool _toolTipShown = false;
private bool IsTransparent(PictureBox pb, MouseEventArgs e)
{
Color pixel = ((Bitmap)pb.Image).GetPixel(e.X, e.Y);
return (0 == pixel.A && 0 == pixel.R && 0 == pixel.G && 0 == pixel.B);
}
private void DisplayToolTip(object sender, MouseEventArgs e)
{
Control control = (Control)sender;
IsTransparent((PictureBox)control, e);
if (IsTransparent((PictureBox)control, e))
{
_toolTip.Hide(control);
_toolTipShown = false;
}
else
{
if (!_toolTipShown)
{
_toolTip.Show(control.Tag.ToString(), control);
_toolTipShown = true;
}
}
}

How to get the index of dynamically created multiple panels in C# GUI form,when a checkbox is clicked in one of the dynamically created panel

I have a split container panel in GUI Form.When a button is clicked in left panel,it pulls out information along with multiple checkboxes on dynamically created panels on the right panel using a loop.Each panel on the right side can have multiple checkboxes based on some condition.For example, the first panel has one checkbox and the second panel below the first has got 8 checkboxes in the same row.When one of the checkboxes in second panel is clicked, I have to get the index of the that panel to do some manipulation. Tab index does not help me to get one as each panel can have any number of checkboxes.I spent a day to get around the problem with no luck. Your help will be much appreciated. I have posted the code below.
for (int j = 0; j < numOfSensors.Count; j++)
{
sensorpanel = new Panel();
sensorpanel.Size = new Size(800, 60);
sensorpanel.Location = new Point(0, Y);
sensorpanel.BackColor = Color.LightGray;
sensorpanel.Paint += new PaintEventHandler(panel_Paint);
Button sensor = new Button();
sensor.Size = new Size(200, 50);
sensor.Location = new Point(1, 1);
sensor.FlatStyle = FlatStyle.Flat;
sensor.FlatAppearance.BorderColor = Color.LightGray;
String sensorType = "Occupancy";
sensor.TextAlign = ContentAlignment.MiddleLeft;
sensor.BackColor = Color.LightGray;
sensor.ForeColor = Color.Black;
sensorpanel.Controls.Add(sensor);
if (sensorType.Equals("Occupancy"))
{
CheckBox cb = new CheckBox();
cb.Location = new Point(380, 15);
cb.Size = new Size(20, 17);
cb.Checked = checkBox(j,0);
cb.Text = "Occupancy";
checksensorbuttons.Add(cb);
cb.CheckedChanged += new EventHandler(cb_CheckChanged);
sensorpanel.Controls.Add(cb);
}
else if (sensorType.Equals("Multi-input:Digital"))
{
int xLoc = 210;
int yLoc = 15;
for (int k = 16; k <32; k+=2)
{
CheckBox cb = new CheckBox();
cb.Location = new Point(xLoc, yLoc);
cb.Size = new Size(20, 17);
cb.Checked = checkBox(j,k);
cb.Text = "Multi-input";
cb.CheckedChanged += new EventHandler(cb_CheckChanged);
sensorpanel.Controls.Add(cb);
xLoc += 30;
}
splitContainer.panel2.Controls.Add(sensorpanel);
}
//checkedchanged eventhandler
private void cb_CheckChanged(object sender, EventArgs e)
{
CheckBox checkbox = (CheckBox)sender;
if (checkbox.Text.Equals("Occupancy"))
{
// How to get the index of the panel when a checkbox in corresponding panel is checked?
if (checkbox.Checked == true)
{
//some manipulation
}
else
{
//some manipulation
}
}
else if (checkbox.Text.Equals("Multi-input"))
{
//get index of the panel where one of the checkboxes are clicked
if (checkbox.Checked == true)
{
//do some manipulation
}
else
{
//do some manipulation
}
}
There are multiple ways
Use Name property of the checkbox. When the checkbox is created assign it a logical name which makes it easier to identify it. Only string can be used here.
Use Tag property of the checkbox to preserve the data you want to refer it. Its good place to store any object and not just string.
Use Parent property of the checkbox to access checkbox's parent properties.
As a best practice, assign a logical name to the dynamic controls. This is the best way to identify the control.
sensorpanel.Name = "panel" + j.ToString();
this.Controls.Add(sensorpanel);
:
:
cb.Text = "Occupancy";
cb.Tag = "panel Index = " + j.ToString();
cb.Name = "panel" + j.ToString() + "_" + "cb_" + cb.Text;
sensorpanel.Controls.Add(cb);
void cb_CheckedChanged(object sender, EventArgs e)
{
CheckBox checkbox = (CheckBox)sender;
string mssg;
mssg = "Name = " + checkbox.Name;
mssg = "tag = " + checkbox.Tag;
mssg = "Parent text = " + checkbox.Parent.Text;
mssg = "Parent name = " + checkbox.Parent.Name;
MessageBox.Show(mssg);
}

Create labels dynamically depending of CheckedListBox c# winforms

I have a checkedListBox in a TabControl
What I want is to create a label and NumericUpDown dynamically, when User check an item of checkedListBox it will show the new label and NumericUpDown
Then , when it Unchecked this item ,The numericUpDown will be clear (empty).
Conclusion: As many checked items , as many w've create labels and NumericUpDowns.
Please, how will I do that ??
For each checkbox item in your checkedListBox in properties switch to events and create subscriber checkBoxName_CheckStateChanged for event CheckStateChanged.
The code in the sucriber can be like this:
private void checkBox1_CheckStateChanged(object sender, EventArgs e)
{
var source = sender as CheckBox;
if (source.Checked == true)
{
this.numericUpDown1.Text = "TextWhenChecked";
this.labelAtTheNumericUpDown.Text = "TextWhenChecked";
}
else
{
this.numericUpDown1.Text = "TextWhenUnchecked";
this.label1.Text = "TextWhenUnchecked";
}
}
You fill the strings as you want. These are only examples.
To have only checkBox checked at a time look at here: https://stackoverflow.com/a/24693858/6650581.
What you need to do is creating Label and NumericUpDown manually and show it by adding to Controls collection. A TableLayoutPanel can help you arranging controls without setting Size and calculate Location manually.
Here is an example:
public class MainForm : Form
{
private CheckedListBox checkedListBox;
private TableLayoutPanel tableLayoutPanel;
public MainForm()
{
InitializeComponent();
//Fill checkedListBox and create controls
for( int i = 0; i <= 5; i++ )
{
checkedListBox.Items.Add( i.ToString() );
Label lbl = new Label()
{
Name = "lbl" + i,
Text = "Label " + i,
Visible = false
};
NumericUpDown num = new NumericUpDown()
{
Name = "num" + i,
Value = i,
Visible = false
};
tableLayoutPanel.Controls.Add( lbl, 0, i );
tableLayoutPanel.Controls.Add( num, 1, i );
}
}
private void checkedListBox_ItemCheck( object sender, ItemCheckEventArgs e )
{
if( e.NewValue == CheckState.Checked )
{
tableLayoutPanel.Controls["lbl" + e.Index].Visible = true;
tableLayoutPanel.Controls["num" + e.Index].Visible = true;
}
else
{
tableLayoutPanel.Controls["lbl" + e.Index].Visible = false;
((NumericUpDown)tableLayoutPanel.Controls["num" + e.Index]).Value = 0M;
}
}
private void InitializeComponent()
{
this.checkedListBox = new System.Windows.Forms.CheckedListBox();
this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
this.SuspendLayout();
//
// checkedListBox
//
this.checkedListBox.Location = new System.Drawing.Point(8, 8);
this.checkedListBox.Name = "checkedListBox";
this.checkedListBox.Size = new System.Drawing.Size(200, 100);
this.checkedListBox.TabIndex = 1;
this.checkedListBox.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.checkedListBox_ItemCheck);
//
// tableLayoutPanel
//
this.tableLayoutPanel.AutoScroll = true;
this.tableLayoutPanel.ColumnCount = 2;
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel.Location = new System.Drawing.Point(8, 112);
this.tableLayoutPanel.Name = "tableLayoutPanel";
this.tableLayoutPanel.Size = new System.Drawing.Size(200, 100);
this.tableLayoutPanel.TabIndex = 2;
//
// MainForm
//
this.ClientSize = new System.Drawing.Size(223, 227);
this.Controls.Add(this.tableLayoutPanel);
this.Controls.Add(this.checkedListBox);
this.Name = "MainForm";
this.ResumeLayout(false);
}
}

dynamically creating window form according to data returned from dataset (C#)

I have a dataset that returns questions and answers from the database, each answer in answer table is linked via a forgein key to the question table.
What I would like to achive is the following:
That a a single dynamic form is created on the first question with all the questions listed under it, meaning the FK_table_Answers = PK_table_Questions on the table_Answers:
(eg) This is Form for Question One:
Question One: How old are you?
Answer One (this is a radio button)
Answer Two (this is a radio button)
Answer Three (this is a radio button)
I have managed to get the above kind of working but the problem is my code keeps generating the forms (eg) 3 times becuase there are three answers, so can anyone point me in right direction how to generate the form dynamically but only ONCE - meaning each successive form is created only once as per the question and that particular questions answers under it.
Kind regards
UPDATED code:
private void LoadDataSets()
{
if (_dataSetQuestionnaire.tbl_QuestionnaireQuestion.Rows.Count == 0)
{
try
{
//Questionnaire:
DataSet1TableAdapters.tbl_QuestionnaireTableAdapter questionnaireAdapter =
new DataSet1TableAdapters.tbl_QuestionnaireTableAdapter();
questionnaireAdapter.Fill(_dataSetQuestionnaire.tbl_Questionnaire);
//Category:
DataSet1TableAdapters.tbl_QuestionnaireCategoryTableAdapter categoryAdapter =
new DataSet1TableAdapters.tbl_QuestionnaireCategoryTableAdapter();
categoryAdapter.Fill(_dataSetQuestionnaire.tbl_QuestionnaireCategory);
//QuestionnaireQuestion:
DataSet1TableAdapters.tbl_QuestionnaireQuestionTableAdapter questionnaireQuestionAdapter =
new DataSet1TableAdapters.tbl_QuestionnaireQuestionTableAdapter();
questionnaireQuestionAdapter.Fill(_dataSetQuestionnaire.tbl_QuestionnaireQuestion);
//QuestionnaieAnswer:
DataSet1TableAdapters.tbl_QuestionnaireAnswerTableAdapter questionnaireAnswerAdapter =
new DataSet1TableAdapters.tbl_QuestionnaireAnswerTableAdapter();
questionnaireAnswerAdapter.Fill(_dataSetQuestionnaire.tbl_QuestionnaireAnswer);
using (DataSet1 dSet = new DataSet1())
{
//Questionnaire:
dSet.Merge(_dataSetQuestionnaire.tbl_Questionnaire);
//Category:
dSet.Merge(_dataSetQuestionnaire.tbl_QuestionnaireCategory);
//QuestionnaireQuestion:
dSet.Merge(_dataSetQuestionnaire.tbl_QuestionnaireQuestion);
//QuestionnaieAnswer:
dSet.Merge(_dataSetQuestionnaire.tbl_QuestionnaireAnswer);
int primaryKeyQuestionnaire = Convert.ToInt32(_dataSetQuestionnaire.tbl_Questionnaire.Rows[0][0]);
foreach (DataSet1.tbl_QuestionnaireRow questionnaire
in _dataSetQuestionnaire.Tables["tbl_Questionnaire"].Select(String.Format("pk_tbl_Questionnaire = {0}", primaryKeyQuestionnaire)))
{
foreach (DataSet1.tbl_QuestionnaireCategoryRow category
in _dataSetQuestionnaire.Tables["tbl_QuestionnaireCategory"].Select(String.Format("fk_tbl_Questionnaire = {0}", questionnaire.pk_tbl_Questionnaire)))
{
foreach (DataSet1.tbl_QuestionnaireQuestionRow question
in _dataSetQuestionnaire.Tables["tbl_QuestionnaireQuestion"].Select(String.Format("fk_tbl_QuestionnaireCategory = {0}", category.pk_tbl_QuestionnaireCategory)))
{
int radiobuttonPosition = 0;
foreach (DataSet1.tbl_QuestionnaireAnswerRow answer
in _dataSetQuestionnaire.Tables["tbl_QuestionnaireAnswer"].Select(String.Format("fk_tbl_QuestionnaireQuestion = {0}", question.pk_tbl_QuestionnaireQuestion)))
{
//Gets the questins via the FK_questionnaireQuestion and fill the _dataSetRadioButtons to generate on dynamic form.
DataSet1TableAdapters.tbl_QuestionnaireAnswerTableAdapter a =
new DataSet1TableAdapters.tbl_QuestionnaireAnswerTableAdapter();
DataSet dSetRadioButtons = new DataSet();
dSetRadioButtons.Merge(a.GetDataByQuestionnaireQuestion(answer.fk_tbl_QuestionnaireQuestion));
_dataSetRadioButtons = dSetRadioButtons;
string theQuestion = question.tbl_QuestionnaireQuestion_Description.ToString();
Form form = new Form();
_form = form;
if(_form == null)
{
_form = new Form();
}
else
{
form.Height = 400;
form.Width = 550;
form.StartPosition = FormStartPosition.CenterScreen;
Label label = new Label();
label.Location = new System.Drawing.Point(5, 10);
label.Size = new System.Drawing.Size(450, 25);
label.Text = theQuestion;
Panel panel = new Panel();
panel.Size = new System.Drawing.Size(300, 200);
panel.Location = new System.Drawing.Point(15, 50);
panel.BackColor = Color.Yellow;
System.Windows.Forms.RadioButton[] radioButtons = new System.Windows.Forms.RadioButton[_dataSetRadioButtons.Tables["tbl_QuestionnaireAnswer"].Rows.Count];
for (int i = 0; i < _dataSetRadioButtons.Tables["tbl_QuestionnaireAnswer"].Rows.Count; i++)
{
radioButtons[i] = new RadioButton();
radioButtons[i].Text = _dataSetRadioButtons.Tables["tbl_QuestionnaireAnswer"].Rows[i]["tbl_QuestionnaireAnswer_Description"].ToString();
radioButtons[i].Location = new System.Drawing.Point(60, 20 + i * 20);
//panel.Controls.Add(radioButtons[i]);
radioButtons[i].Click += new EventHandler(Form1_Click);
Int64 item = Convert.ToInt64(_dataSetRadioButtons.Tables["tbl_QuestionnaireAnswer"].Rows[0].ItemArray[3].ToString());
panel.Controls.Add(radioButtons[i]);
}
Button nextButton = new Button();
nextButton.Text = "Next";
nextButton.Name = "button";
nextButton.Location = new System.Drawing.Point(200, 300);
nextButton.Size = new System.Drawing.Size(150, 25);
nextButton.Click += new EventHandler(nextButton_Click);
form.Controls.AddRange(new Control[] { panel, label, nextButton });
form.ShowDialog();
CreateBoxAndQuestion(form, panel, label);
//form.Dispose();
}
}
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else
{
MessageBox.Show("Error");
}
}
private void CreateBoxAndQuestion(Form f, Panel p, Label l)
{
for (int i = p.Controls.Count - 1; i >= 0; i--)
{
p.Controls.RemoveAt(i);
}
}
If I understand correctly, you call CreateBoxAndQuestion every time a new question is selected.
But you create (and destroy) the form each time your code enters in this method.
A first approach would be to keep the form, label, button and panel creation outside the method (perhaps in design mode) then passing these controls to the method as
EDIT: Somewhere in your code before entering the load of your next question:
frmQuestion _form = null; // Global
// Create a global instance and keep it without displaying
if(_form == null) _form = new frmQuestion(); // frmQuestion created with panel, label e button via FormDesigner
then when you need to populate _form call
CreateBoxAndQuestion(_form, _form.Panel, _form.Label, questionText);
In this example I pass the _form to CreateBoxAndQuestion, but this is not necessary because is a global. You could change CreateBoxAndQuestion to use directly the global instance.
private void CreateBoxAndQuestion(frmQuestion f, Panel p, Label l, string _label)
{
// Do not display your form here....
}
Now when entering the method clear every RadioButton controls in the panel.Controls collection
for (int i = p.Controls.Count - 1; i >= 0; i--)
{
p.Controls.RemoveAt(i);
}
the rest of the code should change only to reflect the new text assigned to the label and controls and the re-adding of the RadioButtons to the panel. No more creation and reinitialization for Form Label, Button.
label.Text = _label;
Don't forget to destroy _form at the end of your program with _form.Dispose();

Categories

Resources