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);
Related
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}");
}
}
}
}
I have seem some questions similar to this but not exactly this so. Im trying to make multiple selection in a DataGridView with only one column and multiple rows. I want the capability to select and unselect with normal click (without pressing Ctrl) and that the selection remains until I click again. I got
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
dataGridView1.Rows.Add();
dataGridView1.Rows.Add();
dataGridView1.Rows.Add();
}
DataGridView1.MultipleSelect = true;
DataGridView1.SelectMode = GridViewSelectMode.SelectCells;
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
//handle the keep select/unselect group
}
but how do I set up the condition of not using Ctrl key to keep the selection? Thanks
You can select the cells yourself by tweaking a bit the color schemes of the grid and store/remove them in/from a list when they are clicked:
public partial class Form1 : Form
{
/// <summary>
/// Currently selected cells.
/// </summary>
private List<DataGridViewCell> _selectedCells = new List<DataGridViewCell>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
/* Just for test
dataGridView1.Columns.Add("A", "ColA");
dataGridView1.Columns.Add("B", "ColB");
dataGridView1.Columns.Add("C", "ColC");
dataGridView1.Columns.Add("D", "ColD");
dataGridView1.Rows.Add("A1","B1","C1","D1");
dataGridView1.Rows.Add("A2", "B2", "C2", "D2");
dataGridView1.Rows.Add("A3", "B3", "C3", "D3");
dataGridView1.Rows.Add("A4", "B4", "C4", "D4");
dataGridView1.Rows.Add("A5", "B5", "C5", "D5");
dataGridView1.Rows.Add("A6", "B6", "C6", "D6");
*/
dataGridView1.MultiSelect = false;
dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;
dataGridView1.EditMode = DataGridViewEditMode.EditProgrammatically;
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
// Edited and added this line to avoid problems when clicking on the header.
if (e.RowIndex < 0 || e.ColumnIndex < 0) return;
// Clears all the selected cells.
dataGridView1.ClearSelection();
if (_selectedCells.Contains(dataGridView1[e.ColumnIndex, e.RowIndex]))
{
_selectedCells.Remove(dataGridView1[e.ColumnIndex, e.RowIndex]);
dataGridView1[e.ColumnIndex, e.RowIndex].Style.BackColor = dataGridView1.DefaultCellStyle.BackColor;
}
else
{
_selectedCells.Add(dataGridView1[e.ColumnIndex, e.RowIndex]);
dataGridView1[e.ColumnIndex, e.RowIndex].Style.BackColor = dataGridView1.DefaultCellStyle.SelectionBackColor;
}
}
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
dataGridView1.ClearSelection();
}
private void dataGridView1_DoubleClick(object sender, EventArgs e)
{
dataGridView1.BeginEdit(true);
}
}
I have a CheckedListBox with 10 items. On each item check a method is being called. I want to disable the checkbox of that particular item for which the method is being executed so that user cannot uncheck the item till the job is completed.
Note: Unchecking of an item calls another method.
Here is the code of ItemCheck Event:
private void host_listbox_ItemCheck(object sender, ItemCheckEventArgs e)
{
int index = e.Index;
try
{
string sitem = host_listbox.Items[index].ToString();
host_list[sitem].checked_event=e;
if (!host_list[sitem].is_busy)
{
host_config.listEnabled = false;
host_list[sitem].con_worker.RunWorkerAsync();
}
if (host_listbox.GetItemCheckState(index) == CheckState.Checked)
{
host_list[sitem].connected = false;
}
}
catch(Exception ex)
{
output_textbox.AppendText("connection failed!" +ex.ToString() +Environment.NewLine);
}
}
You can check/uncheck items in your checkedListBox with this code
checkedListBox.SetItemChecked(item, true);
for more informations go to microsoft documentation
private void host_listbox_ItemCheck(object sender, ItemCheckEventArgs e)
{
int index = e.Index;
try
{
string sitem = host_listbox.Items[index].ToString();
if (host_list[sitem].is_busy // or whatever indicates that background worker is running or any condition that specifies, that you do not want to let this item to be changed)
e.NewValue = e.CurrentValue; //Change the value back
else
{
//Let the checked state of the item change
This code prevent checked state change if associated background work is running:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
workerList = new List<BackgroundWorker>();
for (int i = 0; i < 10; i++)
{
var el = new BackgroundWorker();
el.DoWork += (s, e) =>
{
Thread.Sleep(5000);
};
workerList.Add(el);
checkedListBox1.Items.Add("el " + i);
}
}
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
var worker = workerList[e.Index];
if (worker.IsBusy)
{
e.NewValue = e.CurrentValue;
return;
}
if (e.NewValue == CheckState.Checked)
worker.RunWorkerAsync();
}
public List<BackgroundWorker> workerList { get; set; }
}
Think, that only funcion solution is set selection mode
CheckedListBox.SelectionMode = SelectionMode.None;
private void ItemCheck(object sender, ItemCheckEventArgs e)
{
if (busy)
e.NewValue = e.CurrentValue;
}
Im trying to create a array of Checkboxes in Winforms and I have four Checkboxes and if I click on a Checkbox, a messagebox should display the checkboxes checked.
public void checkboxtest()
{
CheckBox[] boxes = new CheckBox[4];
boxes[0] = checkBox1;
boxes[1] = checkBox2;
boxes[2] = checkBox3;
boxes[3] = checkBox4;
for (int i = 0; i <= 4; i++)
{
if (boxes[i].Checked == true && boxes[i].Enabled)
{
MessageBox.Show("boxes[i] is clicked");
}
}
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
checkboxtest();
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
checkboxtest();
}
continues for 3 and 4 too...
How should I go about it ??
Thanks.
Your loop termination should be i < 4, not i <= 4 since your array only has 4 elements. Also boxes[i].Checked == true is redundant, you can just say boxes[i].Checked.
If you want to display the checked checkboxes when you toggle the state, you'll need to add an event handler to them (to handle the CheckBox.CheckChanged event):
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
_checkBoxes = new CheckBox[] { _checkBox1, _checkBox2, _checkBox3, _checkBox4 };
foreach (var checkBox in _checkBoxes)
checkBox.CheckedChanged += new EventHandler(ShowCheckedCheckboxes);
}
void ShowCheckedCheckboxes(object sender, EventArgs e)
{
string message = string.Empty;
for (int i = 0; i < _checkBoxes.Length; i++)
{
if (_checkBoxes[i].Checked && _checkBoxes[i].Enabled)
{
message += string.Format("boxes[{0}] is clicked\n", i);
}
}
MessageBox.Show(message);
}
CheckBox[] _checkBoxes;
}
I have a winform with a listbox and a treeview.
Once my listbox is filled with items, I want to drag them (multiple or single) from the listbox and drop them in a node in the treeview.
If somebody has a good example in C# that would be great.
It's been a while since I've messed with Drag/Drop so I figured I'll write a quick sample.
Basically, I have a form, with a listbox on the left, and a treeview on the right. Then I put a button on top. When the button is clicked, it just puts the date of the next ten days into the list box. It also populates the TreeView with 2 parents nodes and two child nodes. Then, you just have to handle all the subsequent drag/drop events to make it work.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.treeView1.AllowDrop = true;
this.listBox1.AllowDrop = true;
this.listBox1.MouseDown += new MouseEventHandler(listBox1_MouseDown);
this.listBox1.DragOver += new DragEventHandler(listBox1_DragOver);
this.treeView1.DragEnter += new DragEventHandler(treeView1_DragEnter);
this.treeView1.DragDrop += new DragEventHandler(treeView1_DragDrop);
}
private void button1_Click(object sender, EventArgs e)
{
this.PopulateListBox();
this.PopulateTreeView();
}
private void PopulateListBox()
{
for (int i = 0; i <= 10; i++)
{
this.listBox1.Items.Add(DateTime.Now.AddDays(i));
}
}
private void PopulateTreeView()
{
for (int i = 1; i <= 2; i++)
{
TreeNode node = new TreeNode("Node" + i);
for (int j = 1; j <= 2; j++)
{
node.Nodes.Add("SubNode" + j);
}
this.treeView1.Nodes.Add(node);
}
}
private void treeView1_DragDrop(object sender, DragEventArgs e)
{
TreeNode nodeToDropIn = this.treeView1.GetNodeAt(this.treeView1.PointToClient(new Point(e.X, e.Y)));
if (nodeToDropIn == null) { return; }
if(nodeToDropIn.Level > 0)
{
nodeToDropIn = nodeToDropIn.Parent;
}
object data = e.Data.GetData(typeof(DateTime));
if (data == null) { return; }
nodeToDropIn.Nodes.Add(data.ToString());
this.listBox1.Items.Remove(data);
}
private void listBox1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void treeView1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
this.listBox1.DoDragDrop(this.listBox1.SelectedItem, DragDropEffects.Move);
}
}
You want to use the GetItemAt(Point point) function to translate X,Y location to the listview item.
Here's quite good article about it: Drag and Drop Using C#.
To make the item being dragged visible while dragging, you need to use COM ImageList, which is well described in the following article Custom Drag-Drop Images Using ImageLists.