Radio button set needs a selection limit in custom control - c#

public HtmlGenericControl fieldset = new HtmlGenericControl("fieldset");
public HtmlGenericControl legend = new HtmlGenericControl("legend");
String[] options = ListString.Split(',');
for (int i = 0; i < options.Length; i++)
{
RadioButton aRadioButton = new RadioButton();
aRadioButton.Text = options[i];
fieldset.Controls.Add(aRadioButton);
}
fieldset.Controls.add(legend)
Yet when the radio list appears on my page, multiple radio buttons are selectable. How do I restrict the selection limit to 1?

Try this:
aRadioButton.GroupName = "myGroup";
Each RadioButton must be in a group so that it knows when to deselect the others from the same group.

Related

Changing order of controls in flow layout panel during runtime

I have a Windows form on which I put a flow layout panel. I also have a class that reads a local database and returns the corresponding values. Depending on the user input via a button(s) the panel gets filled with other buttons. The amount of these buttons depends on the values in the local database. The buttons are displayed correctly and with the correct information, but the order in which they are displayed is alphabetical even though the data-table, from the database class, is ordered in the correct way (via the numerical value of the "ID" column from the database).
I have also added a data-grid view to check and there the items are displayed in the correct way. I have tried to add a for-each loop but that just seems to randomize the order of the buttons.
Does anybody know how I can get the buttons to be displayed in the correct way, so that the button with the lowest "ID" value gets displayed first.
Here is the code for displaying the buttons:
//set the datagridview with the correct values/names. Order works perfectly
dataGridView_AttackName.DataSource = db.attackIDName(attackCategory, taughtOn);
DataTable dt = db.attackIDName(attackCategory, taughtOn);
//sort datable again because doesnt work from db class
dt.DefaultView.Sort = "ID";
dt.DefaultView.ToTable();
int horizontal = 0;
int vertical = 0;
Button[] buttonArray = new Button[dt.Rows.Count];
for (int items = 0; items < buttonArray.Length; items++)
{
buttonArray[items] = new Button();
buttonArray[items].Size = new Size(150, 50);
buttonArray[items].Location = new Point(horizontal, vertical);
buttonArray[items].Name = string.Format("Button_{0}", dt.Rows[items]["ID"].ToString());
buttonArray[items].Text = dt.Rows[items]["Name"].ToString();
buttonArray[items].Click += btn_msg;
if ((items + 1) < buttonArray.Length)
{
vertical += 50;
}
flowLayoutPanel_AttackName.Controls.Add(buttonArray[items]);
}
//get the correct ID value from the button name and try to order it that way
foreach (Button b in flowLayoutPanel_AttackName.Controls)
{
string name = b.Name;
string subname = name.Substring(name.IndexOf("_") + 1);
int i = Convert.ToInt32(subname);
flowLayoutPanel_AttackName.Controls.SetChildIndex(b, i);
}
I have searched around on this site but couldn't find anything that worked.
You've correctly sorted the DefaultView by the ID, but then haven't used the results!
You need to replace, for example, dt.Rows[items]["Name"]with dt.DefaultView[items].Row["Name"]. You then don't need the statement dt.DefaultView.ToTable().
Full code is below:
dt.DefaultView.Sort = "ID";
int horizontal = 0;
int vertical = 0;
Button[] buttonArray = new Button[dt.Rows.Count];
for (int items = 0; items < buttonArray.Length; items++)
{
buttonArray[items] = new Button();
buttonArray[items].Size = new Size(150, 50);
buttonArray[items].Location = new Point(horizontal, vertical);
buttonArray[items].Name = string.Format("Button_{0}", dt.DefaultView[items].Row["ID"].ToString());
buttonArray[items].Text = dt.DefaultView[items].Row["Name"].ToString();
buttonArray[items].Click += btn_msg;
if ((items + 1) < buttonArray.Length)
{
vertical += 50;
}
flowLayoutPanel_AttackName.Controls.Add(buttonArray[items]);
}

Re-loading Dynamic RadioButtonList on postback

I am creating an application where different kinds of survey questions are pulled from a database.
The first kind I am implementing is a list of questions each with four radio buttons to choose from.
My code for creating the radio button lists and mark up dynamically is
protected void ProcessData(DataTable question, DataTable answers)
{
int i = 0;
foreach (DataRow row in question.Rows)
{
HtmlGenericControl rowDiv = new HtmlGenericControl("div");
rowDiv.Attributes["class"] = "classRowDiv";
panel1.Controls.Add(rowDiv);
HtmlGenericControl questionDiv = new HtmlGenericControl("div");
questionDiv.Attributes["class"] = "classQuestionDiv";
questionDiv.ID = "questionDiv" + i.ToString();
rowDiv.Controls.Add(questionDiv);
Label questionLabel = new Label();
questionLabel.Attributes["class"] = "classQuestionLabelDiv";
if (row[2].ToString() == "Radio button")
{
questionLabel.Text = row[3].ToString();
rowDiv.Controls.Add(questionLabel);
HtmlGenericControl radioDiv = new HtmlGenericControl("div");
radioDiv.Attributes["class"] = "classRadioDiv";
radioDiv.ID = "radioDiv" + i.ToString();
rowDiv.Controls.Add(radioDiv);
RadioButtonList rbl = new RadioButtonList();
rbl.ID = "List" + i.ToString();
radioDiv.Controls.Add(rbl);
rbl.RepeatDirection = RepeatDirection.Horizontal;
Label lbl = new Label();
lbl.Text = "<hr />";
panel1.Controls.Add(lbl);
DataRow rowA;
for (int j = 0; j < 4; j++ )
{
rowA = answers.Rows[j];
ListItem button = new ListItem(rowA[2].ToString(), j.ToString());
button.Attributes["class"] = "radioStyle";
rbl.Items.Add(button);
}
i++;
}
}
}
The problem I am having is actually getting the selected values of the buttons. I have come to understand from reading around that dynamically created controls must be re-loaded with the same ID after a postback but I do not fully understand how to achieve this as the amount of radio buttons created is dependent on the result set from the database.

Set selected value in dynamically created combo boxes

I have created dynamic combo boxes but i am not able to set the value of the combo box
var list = new List<string>() { "Add","Sub","Mul","Div"};
for (int i = 0; i < 10; i++)
{
var c = new ComboBox();
c.DataSource = list.ToList();
c.selectedvalue="Sub";
this.flowLayoutPanel1.Controls.Add(c);
}
You are setting the DataSource of your ComboBox and trying to set the SelectedValue but for this to work correctly you need to set the ValueMember to the name of a member property of your datasource. But, in your case, having a simple list of strings, you cannot use any meaningful property name for SelectedValue.
Change your code to
List<string> list = new List<string>() { "Add","Sub","Mul","Div"};
for (int i = 0; i < 10; i++)
{
var c = new ComboBox();
c.Items.AddRange(list.ToArray());
c.SelectedIndex = 1;
this.flowLayoutPanel1.Controls.Add(c);
}
Of course you could make this more generic using the IndexOf("Sub") to retrieve the index and replace the fixed 1 that I have used, but in this case it seems useless.
To select a default value of a combobox use the below code.
c.SelectedIndex = 1;
This will set the start position at the first item in your list.

Flow Layout Panel Population C#

I'm trying to populate a Flow Layout Panel with ComboBoxes and NumbericUpDowns.
The problem I'm having is using both the new NumbericUpDowns with the new ComboBoxes. Here is how I'm generating the ComboBoxes and NumericUpDowns.
// This int increments each time the code is run. It's located outside of the method below.
int captchaID = 0;
.
// Textboxes that are only for the UI, no code interaction based on text input.
string textboxText = "captchaTextbox";
TextBox newTextbox = new TextBox();
newTextbox.Name = captchaID.ToString() + textboxText;
newTextbox.Text = "";
newTextbox.Width = 175;
itemFlowPanel.Controls.Add(newTextbox);
// Combo Boxes
string comboBoxText = "captchaComboBox";
ComboBox newComboBox = new ComboBox();
newComboBox.Name = captchaID.ToString() + comboBoxText;
newComboBox.Width = 50;
newComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
itemFlowPanel.Controls.Add(newComboBox);
// This array holds my strings that are added to each ComboBox
string[] skills = new string[6];
skills[0] = "STR";
skills[1] = "DEX";
skills[2] = "CON";
skills[3] = "INT";
skills[4] = "WIS";
skills[5] = "CHA";
// This for loop is just populating my ComboBox with the array.
for (int i = 0; i < skills.Length; i++)
{
newComboBox.Items.Add(skills[i]);
}
// Numeric Up Downs
string numericUpDownText = "captchaNumericUpDown";
NumericUpDown newNumericUpDown = new NumericUpDown();
newNumericUpDown.Name = captchaID.ToString() + numericUpDownText;
newNumericUpDown.Width = 50;
newNumericUpDown.ValueChanged += new EventHandler(captchaNumericUpDown_Click);
newNumericUpDown.ValueChanged += new EventHandler(captchaNumericUpDown_ValueChanged);
itemFlowPanel.Controls.Add(newNumericUpDown);
captchaID++;
With the current code, I'm able to edit an EventHandler that each NumericUpDown contains, but I haven't found a way to make it able to read it's corresponding combobox (which increment together with captchaID).
What I'd like to be able to do, is create a new unique event for each, but if that's not possible, a way to check the ID of the combobox would help as well.
Here are quick solutions:
1) By using dictionary
Dictionary<NumericUpDown, ComboBox> _controls = new Dictionary<NumericUpDown, ComboBox>();
// when you create comboBox - add entry with associated numericUpDown
_controls.Add(numericUpDown1, comboBox1);
// now in the numericUpDown event you can get combobox like this
void numericUpDown_Whatever(object sender, WhateverEventArgs e)
{
var numericUpDown = (NumericUpDown)sender;
var comboBox = _controls[numericUpDown];
// do something
var selectedIndex = comboBox.SelectedIndex;
...
}
2) By using Tag
// add combobox into numericUpDown Tag when you create them
numericUpDown1.Tag = comboBox1;
// now in the numericUpDown event you can get combobox like this
void numericUpDown_Whatever(object sender, WhateverEventArgs e)
{
var numericUpDown = (NumericUpDown)sender;
var comboBox = (CombBox)numericUpDown.Tag;
// do something
var selectedIndex = comboBox.SelectedIndex;
...
}
You can rewrite your captchaNumericUpDown_ events to take a ComboBox as an additional parameter and then call them like this:
newNumericUpDown.ValueChanged += (sender, args) =>
{
captchaNumericUpDown_Click(sender, args, newComboBox);
}

How to make autogeneration of buttons in a form by getting labels and button names from database?

I want to make autogeneration of buttons in a form by getting labels and button names from database.
I'm coding in C# Visual Studio 2013.WinForms.
Tip of direction of how get label names and code it in C# is enough.
Lets say you save the names of the textboxes and labels into lists
List<string> labels = new List<string>();
List<string> textboxes = new List<string>();
Then you just itterate through them, create the controls and put them on your form like this:
for(int a = 0; a< label.count;a++){
Label l = new Label();
l.Location = new Point(5,5+a*20);
l.Text = label[a];
this.Controls.Add(l);
}
for(int a = 0; a< textboxes.count;a++){
TextBox t = new TextBox();
tl.Location = new Point(100,5+a*20);
t.Text = textboxes[a];
this.Controls.Add(t);
}

Categories