at the beginning I will say that I am a beginner in programming, but I want to make a program for work that will randomize the name of an employee. Only names that are checked in the checkbox. It currently randomizes me either from all names or from the most recently selected ones. Names so far marked as: N1, N2, N3, N4, N5: My code below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MNW_v._1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void groupBox1_Enter(object sender, EventArgs e)
{
}
private void N1_CheckedChanged(object sender, EventArgs e)
{
}
private void N2_CheckedChanged(object sender, EventArgs e)
{
}
private void N3_CheckedChanged(object sender, EventArgs e)
{
}
private void N4_CheckedChanged(object sender, EventArgs e)
{
}
private void N5_CheckedChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
string[] tablica = new string[] { N1.Text, N2.Text, N3.Text, N4.Text, N5.Text };
Random rn = new Random();
int obj = rn.Next(0, tablica.Length);
Console.Write(obj);
if (N1.Checked)
{
MessageBox.Show(N1.Text);
}
else if (N2.Checked)
{
MessageBox.Show(N2.Text);
}
else if (N3.Checked)
{
MessageBox.Show(N3.Text);
}
else if (N4.Checked)
{
MessageBox.Show(N4.Text);
}
else if (N5.Checked)
{
MessageBox.Show(N5.Text);
}
}
}
}
I've already tried to create an additional class, but it seems that then checking the boxes does not affect the operation of the program.
CodePudding user response:
I guess this code should help you:
public partial class Form1 : Form
{
private readonly Random random;
public Form1()
{
InitializeComponent();
random = new Random(Guid.NewGuid().GetHashCode());
}
private void ButtonClick(object sender, EventArgs e)
{
List<string> namesList = new List<string>();
foreach (Control control in Controls)
{
CheckBox checkBox = control as CheckBox;
if (checkBox != null && checkBox.Checked)
{
namesList.Add(checkBox.Name);
}
}
if (namesList.Count == 0)
{
MessageBox.Show("Check at least one option!");
}
else
{
int randomIndex = random.Next(0, namesList.Count);
MessageBox.Show(namesList[randomIndex]);
}
}
}
Quick explanation:
- About
new Random(Guid.NewGuid().GetHashCode());
initialisation. This code provides different random values every time you start your application. - I get all controls of form using
Controls
property. That way you can create any amount of checkboxes on form without editing this block of code.
Hope this will help you :)
CodePudding user response:
I'd rather have a array of CheckBox
es, not their Text
s:
using System.Linq;
...
private void button1_Click(object sender, EventArgs e) {
// So we have all CheckBoxes of interest in the collection (array)
// we can query
var boxes = new CheckBox[] {
N1, N2, N3, N4, N5
};
// How many checked CheckBoxes do we have
int count = boxes.Count(box => box.Checked);
// If we have at least one checked CheckBox, we can get random one
string randomName = count > 0
? boxes.Where(box => box.Checked).ElementAt(Random.Shared.Next(count)).Text
: ""; // If none of boxes has been checked
MessageBox.Show(randomName);
}
If Random.Shared
is not supported by your version of .Net, you can use a field:
using System.Linq;
...
private static Random random = new Random();
private void button1_Click(object sender, EventArgs e) {
var boxes = new CheckBox[] {
N1, N2, N3, N4, N5
};
int count = boxes.Count(box => box.Checked);
string randomName = count > 0
? boxes.Where(box => box.Checked).ElementAt(random.Next(count)).Text
: "";
MessageBox.Show(randomName);
}
CodePudding user response:
Your code creates an array, generates a random number, then ignores both and simply chooses the first selected name. What you need to do is create an List of selected names
var names = new List<string>();
if (N1.Checked) names.Add(N1.Text);
if (N2.Checked) names.Add(N2.Text);
...
now generate a random index
Random rn = new Random();
int obj = rn.Next(0, names.Count);
now use that
Console.WriteLine(names[obj]);
CodePudding user response:
Is I understand it, you want to pick one of the checked names at random.
If the CheckedChanged
events are handled by adding or removing the box from a list of checkboxes that are checked then, when you click the Pick button, the _random
(which is a member field, not instantiated each time) is called to to pick a number guaranteed to be less than the Count
of the list.
For example, this code as shown will produce N4, N3, N2, N4, N2... and so on.
For testing purposes, seeding the Random
with a value of 2 when instantiated ensures the same pseudo-random sequence is generated every time. (Otherwise, the default seed value of Random is derived from the system clock and produces a new sequence every time this code is run.)
public partial class MainForm : Form
{
public MainForm() => InitializeComponent();
protected override void onl oad(EventArgs e)
{
base.OnLoad(e);
buttonPick.Click = button1_Click;
foreach (CheckBox checkbox in Controls.Cast<Control>().Where(_ => _ is CheckBox))
{
checkbox.CheckedChanged = onAnyCheckedChanged;
}
}
List<CheckBox> _checkedCheckboxes = new List<CheckBox>();
private void onAnyCheckedChanged(object? sender, EventArgs e)
{
if(sender is CheckBox checkbox)
{
if(checkbox.Checked) _checkedCheckboxes.Add(checkbox);
else _checkedCheckboxes.Remove(checkbox);
Text = $"{_checkedCheckboxes.Count} Selected";
}
}
Random _random = new Random(2);
private void button1_Click(object sender, EventArgs e)
{
BeginInvoke(() => // Don't block the click event
{
if(_checkedCheckboxes.Count == 0){
MessageBox.Show("Check some names first");
}
else{
int randomIndex = _random.Next(0, _checkedCheckboxes.Count);
MessageBox.Show($"Picked: {_checkedCheckboxes[randomIndex].Text}");
}
});
}
}