I'm trying to create a design form in visual studio with 4 checkboxes and I really want to make the user to check only one of them, and if he's not checked one, when he will press a button, he should receive a notification with the obligation to select a box, and the program should not starting.
RadioGroup is a control very similar in appearance to CheckBox. It's used to select only one RadioGroup in each group. You can define groups of radio buttons puttin inside a container (a Form, a Panel, a GroupBox). Add 4 radio buttons to your form, set the Text property.
You can check if a radio button is selected:
var isChecked = radioButton1.Checked;
Or make a method like this:
private int GetSelectedRadioIndex()
{
var buttons = new[]
{
this.radioButton1,
this.radioButton2,
this.radioButton3,
this.radioButton4
};
for (int i = 0; i < buttons.Length; i++)
{
if (buttons[i].Checked)
{
return i;
}
}
return -1;
}
If you get a <0 index, there aren't a radio selected. In other case you have a 0 index of the radio that is selected.
As indicated, use a container like a Panel or GroupBox while with a GroupBox you can set a caption to indicate what the RadioButtons are for.
Create a private list in the form
private List<RadioButton> _radioButtons;
Subscribe to the Form's OnShown event, add the following code where OptionsGroupBox is a GroupBox with four Radio Buttons. This ensures no default selection which is optional.
private void OnShown(object sender, EventArgs e)
{
_radioButtons = OptionsGroupBox.Controls.OfType<RadioButton>().ToList();
_radioButtons.ForEach(rb => rb.Checked = false);
}
Add a button to assert/get their selection.
private void CheckSelectionButton_Click(object sender, EventArgs e)
{
var selection = _radioButtons.FirstOrDefault(x => x.Checked);
if (selection == null)
{
MessageBox.Show("Make a selection");
}
else
{
MessageBox.Show($"You selected {selection.Text}");
}
}
Edit: Working with both Panel and GroupBox
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace RadioButtonApp
{
public partial class Form1 : Form
{
private List<RadioButton> _radioButtonsGroupBox;
private List<RadioButton> _radioButtonsPanel;
public Form1()
{
InitializeComponent();
Shown += OnShown;
}
private void OnShown(object sender, EventArgs e)
{
_radioButtonsGroupBox = OptionsGroupBox.Controls.OfType<RadioButton>().ToList();
_radioButtonsGroupBox.ForEach(rb => rb.Checked = false);
_radioButtonsPanel = OptionsPanel.Controls.OfType<RadioButton>().ToList();
_radioButtonsPanel.ForEach(rb => rb.Checked = false);
}
private void CheckSelectionInGroupBoxButton_Click(object sender, EventArgs e)
{
var selection = _radioButtonsGroupBox.FirstOrDefault(x => x.Checked);
if (selection == null)
{
MessageBox.Show("Make a selection");
}
else
{
MessageBox.Show($"You selected {selection.Text}");
}
}
private void CheckSelectionInPanelButton_Click(object sender, EventArgs e)
{
var selection = _radioButtonsPanel.FirstOrDefault(x => x.Checked);
if (selection == null)
{
MessageBox.Show("Make a selection");
}
else
{
MessageBox.Show($"You selected {selection.Text}");
}
}
}
}
Related
How can I make button property set to enabled=true after all my textboxes are not empty?
I'm learning programming and my apps are simple.
I know how to enable this property when one of my textboxes have text but this is not the case.
Use case is that user need to put data in both textboxes and after that will be able to click btn.
How in most simple way can I validate all form and then enable button?
There are just 2 tb:
https://i.imgur.com/JUslNWE.png
You need to create a TextBox_TextChanged event and subscribe to all text boxes.
private void TextBox_TextChanged(object sender, EventArgs e)
{
int notEmptyTextBoxCount = 0;
int textBoxCount = 0;
foreach (var item in Controls)
{
if (item is TextBox txtb)
{
textBoxCount++;
if (txtb.Text != String.Empty)
notEmptyTextBoxCount++;
}
}
if (textBoxCount == notEmptyTextBoxCount)
button.Enabled = true;
else
button.Enabled = false;
}
Thanks guys for all feedback.
I have managed to do this this way:
private void ValidateTextBoxes()
{
if (loginTextBox.Text.Length != 0 && passTextBox.Text.Length != 0)
{
generateHashBtn.Enabled = true;
}
else
{
generateHashBtn.Enabled = false;
}
}
private void TextBox1_TextChanged(object sender, EventArgs e)
{
ValidateTextBoxes();
}
private void TextBox2_TextChanged(object sender, EventArgs e)
{
ValidateTextBoxes();
}
I don't know much about C# so I apologize in advance if my question has been answered elsewhere. I don't know what to search for.
I'm making a tic tac toe game in windows forms. I've set it up like this: each cell has 2 buttons(x and o) and two labels (X and O). Clicking one of the buttons will change the corresponding label's visible property to true while at the same time disabling (enable=false) the opposite button from being selected. There are 9 cells total. I also have a menu button (reset) that when clicked will enable all buttons and hide all labels so that the game may be re-played.
I'm looking for a way to reset all the items I want without having to individually type code for each item. Is there a way to group the items together so that they can all be fired at once with a minimum of code?
Source code is incomplete as I am still writing the program. I've posted the code for three cells.
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 Tick_Tack_Toe
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void xButton1_Click(object sender, EventArgs e)
{
xLabel1.Visible = true;
oButton1.Enabled = false;
}
private void oButton1_Click(object sender, EventArgs e)
{
oLabel1.Visible = true;
xButton1.Enabled = false;
}
private void xButton2_Click(object sender, EventArgs e)
{
xLabel2.Visible = true;
oButton2.Enabled = false;
}
private void oButton2_Click(object sender, EventArgs e)
{
oLabel2.Visible = true;
xButton2.Enabled = false;
}
private void resetToolStripMenuItem_Click(object sender,
EventArgs e)
{
xButton1.Enabled = true;
oButton1.Enabled = true;
xButton2.Enabled = true;
oButton2.Enabled = true;
xButton3.Enabled = true;
oButton3.Enabled = true;
xLabel1.Visible = false;
oLabel1.Visible = false;
xLabel2.Visible = false;
oLabel2.Visible = false;
xLabel3.Visible = false;
oLabel3.Visible = false;
}
}
}
One way you can do this is to loop through the controls collection. Since you seem to have a standard on the naming of the controls, you can first narrow the collection down to only those whose name begins with 'o' or 'x'. Then, you can look at the type of control, and if it's a label you can hide it, and if it's a button you can enable it:
private void ResetControls()
{
foreach (Control control in this.Controls)
{
// Only look at controls whose names begin with 'o' or 'x'
if (control.Name.StartsWith("o") ||control.Name.StartsWith("x"))
{
// Hide it if it's a label
if(control.GetType() == typeof(Label))
{
control.Visible = false;
}
// Enable it if it's a button
else if (control.GetType() == typeof(Button))
{
control.Enabled = true;
}
}
}
}
You mentioned that all your button and labels are inside their own panel control, which has it's own control collection. So you can modify the code above to first search for panel controls, then search the panel control's control collection for buttons and labels:
private void ResetControls()
{
foreach (Control control in this.Controls)
{
if (control is Panel)
{
var panel = control as Panel;
foreach (Control panelControl in panel.Controls)
{
// Only look at controls whose names begin with 'o' or 'x'
if (panelControl.Name.StartsWith("o") || panelControl.Name.StartsWith("x"))
{
// Hide it if it's a label
if (panelControl is Label)
{
panelControl.Visible = false;
}
// Enable it if it's a button
else if (panelControl is Button)
{
panelControl.Enabled = true;
}
}
}
}
}
}
Note that this is just one possible solution to get you going, but certainly not the best. Normally the controls would be created at runtime, added to a collection of some sort (usually an array called GameBoard or something like that), and placed on the form all by code. Their click events would all be hooked up to the same method, which would do the right thing based on either control name or some data in the Tag field.
They are grouped together in the Controls array of the form. Here is a simple example of how you can cycle through them:
private void doReset()
{
foreach (Control c in this.Controls)
{
if (c.GetType() == typeof(Button))
{
c.Enabled = true;
}
else if (c.GetType() == typeof(Label))
{
c.Visible = false;
}
}
}
You can do some more intelligent logic in there for the specific controls if you like. Something like adding a tag to each button if it gets picked up by the method or, naming each button in a certain way if it is to get picked up by the method.
Let's try following idea:
List<Button> buttons = new List<Button>();
List<Label> labels = new List<Label>();
buttons.Add(xButton1)
buttons.Add(oButton1)
buttons.Add(xButton2)
buttons.Add(oButton2)
...
labels.Add(xLabel1)
labels.Add(oLabel1)
labels.Add(xLabel2)
labels.Add(oLabel2)
...
foreach(var ctr in buttons)
{
ctr.Enabled = true;
}
foreach(var ctr in labels)
{
ctr.Enabled = true;
}
This is how I always do it. If you give each button a different text value inside the click event you can do different things depending on the text value.
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 Tick_Tack_Toe
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
MyButton.buttons = new List<MyButton>() {
new MyButton() { button = xButton1, label = xLabel1},
new MyButton() { button = xButton2, label = xLabel2},
new MyButton() { button = xButton3, label = xLabel3},
new MyButton() { button = oButton1, label = oLabel1},
new MyButton() { button = oButton2, label = oLabel2},
new MyButton() { button = oButton3, label = oLabel3}
};
foreach (MyButton button in MyButton.buttons)
{
button.button.Click += new EventHandler(Button_Click);
}
}
private void Button_Click(object sender, EventArgs e)
{
MyButton button = sender as MyButton;
button.label.Visible = true;
button.button.Enabled = false;
switch (button.button.Text)
{
case "X":
//enter your code here
break;
case "Y":
//enter your code here
break;
}
}
private void resetToolStripMenuItem_Click(object sender,
EventArgs e)
{
foreach (MyButton button in MyButton.buttons)
{
button.button.Enabled = true;
button.label.Visible = false;
}
}
}
public class MyButton
{
public static List<MyButton> buttons { get; set; }
public Button button { get; set; }
public Label label { get; set; }
}
}
I want to disable multiselection in CheckedListBox. I tried
checkedListBoxWersje.SelectionMode = SelectionMode.One
but I still can check multiple items. So I want to unselect last checked item. Is it possible?
Have you considered using a GroupBox with RadioButtons?
If you really want to go with a CheckedListBox consider the following which allows only one item checked at a time.
namespace CheckListBoxSimple_C_Sharp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
checkedListBox1.ItemCheck += checkedListBox1_ItemCheck;
}
private const int maxNumberOfCheckedItems = 1;
void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
CheckedListBox items = (CheckedListBox)sender;
if (items.CheckedItems.Count > (maxNumberOfCheckedItems - 1))
{
e.NewValue = CheckState.Unchecked;
}
}
private void Form1_Load(object sender, EventArgs e)
{
checkedListBox1.Items.AddRange(new string[] { "John", "Paul", "George", "Ringo" });
checkedListBox1.SetItemChecked(1, false);
checkedListBox1.SetItemChecked(3, false);
}
}
}
This is the code that works.
if(e.NewValue.Equals(CheckState.Checked))
for (int i = 0; i < checkedListBox1.Items.Count; ++i)
if (i != e.Index)
checkedListBox1.SetItemChecked(i, false);
I'm trying to display / hide a 2 combo boxes depending on the chosen event type.
What the program should do is: If exhibition is selected, the groupbox of exhibition will be visible, while having the clubbing groupbox hidden.(Vice versa if clubbing is selected)
Code:
namespace Promoter.Forms
public partial class eventCreate : Form
{
public eventCreate()
{
InitializeComponent();
//import enum value to combo box
cmbEventType.DataSource = Enum.GetValues(typeof(EventType));
}
private void eventCreate_Load(object sender, EventArgs e)
{
if (cmbEventType.Text == "Exhibition")
{
grpClubbing.Visible = false;
grpExhibition.Visible = true;
//import enum values to combo box
cmbExhibitionVenue.DataSource = Enum.GetValues(typeof(ExhibitionVenue));
}
else if (cmbEventType.Text == "Clubbing")
{
grpExhibition.Visible = false;
grpClubbing.Visible = true;
//import enum values to combo box
cmbClubbingVenue.DataSource = Enum.GetValues(typeof(ClubbingVenue));
}
}
Try using the SelectedIndexChanged event.
private void cmdEventType_SelectedIndexChanged( object sender, EventArgs e ) {
ComboBox cb = (ComboBox)sender;
grpClubbing.Visible=false;
grpExibition=false;
switch ( cb.SelectedText ) {
case "Exhibition":
grpExhibition.Visible = true;
//import enum values to combo box
cmbExhibitionVenue.DataSource = Enum.GetValues(typeof(ExhibitionVenue));
break;
case "Clubbing":
grpClubbing.Visible = true;
//import enum values to combo box
cmbClubbingVenue.DataSource = Enum.GetValues(typeof(ClubbingVenue));
break;
default:
break;
}
}
Fixed it, just had a logic missing from my mind.
Instead of
private void eventCreate_Load(object sender, EventArgs e)
I had to reason out and do it at:
private void cmbEventType_SelectedIndexChanged(object sender, EventArgs e)
I want to allow user to drag any item from MenuStrip to a ListBox.
I did it between to ListBoxes, but can not do it with MenuStrip.
Thanks a lot for your help.
I use WinForms, C#
For the destination ListBox I modified its property
this.listBox2.AllowDrop = true;
and created the following two events:
private void listBox2_DragOver(
object sender, System.Windows.Forms.DragEventArgs e)
{
e.Effect=DragDropEffects.All;
}
private void listBox2_DragDrop(
object sender, System.Windows.Forms.DragEventArgs e)
{
if(e.Data.GetDataPresent(DataFormats.StringFormat))
{
string str= (string)e.Data.GetData(
DataFormats.StringFormat);
listBox2.Items.Add(str);
}
}
What I need is what should be done to the source MenuStrip to allow drag items from it the ListBox, in over words how to make MenuStrip draggable.
Thanks to all for their help.
I found the solution:
The missing event is that I should add event to ToolStripMenuItem_MouseDown, I prefer to use right click instead of left click to avoid the conflict between ToolStripMenuItem_Click and the drag event, this the code:
AllowDrop = true;
private void tsmi_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
DoDragDrop(sender, System.Windows.Forms.DragDropEffects.Copy);
}
Add also this code to the ListView:
private void lvAllowDropListView_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
System.Windows.Forms.ToolStripMenuItem button = e.Data.GetData(typeof(System.Windows.Forms.ToolStripMenuItem))
as System.Windows.Forms.ToolStripMenuItem;
if (button != null)
{
try
{
SmallImageList = sysIcons.SmallIconsImageList;
LargeImageList = sysIcons.LargeIconsImageList;
System.Windows.Forms.ToolStripMenuItem item = e.Data.GetData(typeof(System.Windows.Forms.ToolStripMenuItem))
as System.Windows.Forms.ToolStripMenuItem;
if (item != null)
{
AddToolStripMenuItem(item.Text, item.Name);
}
}
catch { }
}
}
private void AddToolStripMenuItem(string name, string tag)
{
System.Windows.Forms.ListViewItem item = new System.Windows.Forms.ListViewItem(name);
int Index = -1;
for (int i = 0; i < Items.Count;i++ )
if(Items[i].Tag.ToString() == tag)
{
Index = i;
break;
}
if (Index == -1)
{
item.Tag = tag;
Items.Add(item);
}
}
Drag Menu Strip Item is the same like ListBox item.
Check your code...