Let's say I have a list item populated with a few items, I select one and press delete.
I want something to happen when delete is pressed (and I'd like to know which item or items are selected). If this is possible, I'd like to know how to do this.
Thanks!
Set up your ListView to have an event handler for the KeyDown event. Then check that the key that was pressed was the delete key. Then use SelectedItems to see which items are selected and remove them. Make sure to go from the bottom up because your SelectedItems collection will be constantly changing.
private void listView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Delete)
{
for (int i = listView1.SelectedItems.Count - 1; i >= 0; i--)
{
ListViewItem li = listView1.SelectedItems[i];
listView1.Items.Remove(li);
}
}
}
Related
I want to add an item to the DataGridView
If checked ListBox is checked. but add an item one time.Don't add it twice.
and I want the unchecked object in the checkedlistbox to be deleted as a row in the DataGridView. But my code is not working
Video
private void checkedListBox3_ItemCheck(object sender, ItemCheckEventArgs e)
{
foreach (int indexChecked in checkedListBox3.CheckedIndices)
{
if (checkedListBox3.GetItemCheckState(indexChecked) == CheckState.Checked)
{
dataGridView3.Rows.Add(checkedListBox3.SelectedItem.ToString());
}
else if (checkedListBox3.GetItemCheckState(indexChecked) == CheckState.Unchecked)
{
dataGridView3.Row[indexChecked].Delete;
}
}
}
The problem is that each time the checkedListBox event is fired, you loop through all the checked items and add them to the DGV, hence the duplications.
Instead, you can do this:
private void checkedListBox3_SelectedIndexChanged(object sender, ItemCheckEventArgs e)
{
int selectedIndex = checkedListBox3.SelectedIndex;
// If item is checked, add it to DGV
if (checkedListBox3.GetItemCheckState(selectedIndex) == CheckState.Checked)
{
dataGridView3.Rows.Add(checkedListBox3.Items[selectedIndex].ToString());
}
// If item is unchecked, search for its first occurence in the DGV and remove it
else if (checkedListBox3.GetItemCheckState(selectedIndex) == CheckState.Unchecked)
{
DataGridViewRow row = dataGridView3.Rows
.Cast<DataGridViewRow>()
.First(r => r.Cells["ENTER_YOUR_COLUMN_NAME_HERE"].Value.ToString().Equals(checkedListBox3.Items[selectedIndex].ToString()));
dataGridView3.Rows.Remove(row);
}
}
I would suggest a DerivedCollection. This would work like this:
You have a ReacvtiveList bound to your left panel with checkbox. Person class has to implement INotifyPropertyChanged of course and have Checked property.
Then you can do something like that:
CheckedPeople = People.CreateDerivedCollection(x => x, x => x.Checked);
This will create observable read-only collection storing exactly the same objects that your original list, but filtered by Checked property. Then you can bind CheckedPeople as ItemsSource to your grid and still edit them (only the collection is read only, since it's fed by changes in People collections).
I have a winform with a group of comboboxes, all of the comboboxes with the same list items in them.
I need a way to confirm that when the user is done selecting a value in each box that they only selected each list value once.
Ex:
cbox1 cbox2 cbox 3
Item A Item B Item A (this needs to flag an error since Item A is already selected in cbox1)
I was thinking trying to use the selectedvaluecommited action (as after i populate the list I change the selected index to -1 so they all show "empty" to start) but the loop to make it work seems to be eluding me.
background: this is choosing fields to build a spreadsheet and the user needs to choose the field order.
You can do it like this (quick and dirty):
Add SelectedIndexChanged handler for all three comboboxes (in Form_Load in example)
comboBox1.SelectedIndexChanged += CheckComboBoxes;
comboBox2.SelectedIndexChanged += CheckComboBoxes;
comboBox3.SelectedIndexChanged += CheckComboBoxes;
in CheckComboBoxes method do your checking:
private void CheckComboBoxes(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex == comboBox2.SelectedIndex ||
comboBox1.SelectedIndex == comboBox3.SelectedIndex ||
comboBox2.SelectedIndex == comboBox3.SelectedIndex)
MessageBox.Show("comboboxes are not unique");
}
EDIT:
this is approach when having n comboboxes. Put all items into list, select distinct values and compare that distinct count with items count... Something like this:
private void CheckComboBoxes(object sender, EventArgs e)
{
List<string> comboValues = new List<string>();
foreach (Control c in this.Controls)
{
if (c is ComboBox && !string.IsNullOrEmpty((c as ComboBox).SelectedItem.ToString()))
comboValues.Add((c as ComboBox).SelectedItem.ToString());
}
if (comboValues.Distinct().ToList().Count < comboValues.Count)
MessageBox.Show("not all combos are unique");
}
Here's an approach you can take.
To make the affected comboboxes easy to distinguish, put them all in a GroupBox container.
Write a validation method for your group box.
Subscribe to the group box Validating event by attaching it to your validation method.
In your validation method, loop through all the ComboBox controls in the group box and check if there are any duplicates, and issue an error if so.
For example, assuming the group box is called groupBox1:
private void GroupBox1_Validating(object sender, CancelEventArgs e)
{
base.OnValidating(e);
var selectedIndices = groupBox1.Controls.OfType<ComboBox>().Select(item => item.SelectedIndex);
var anyDuplicates = selectedIndices.GroupBy(x => x).Any(x => x.Count() > 1);
if (!anyDuplicates)
return;
MessageBox.Show("There are duplicates!");
e.Cancel = true;
}
And subscribe to the group box Validating event in the Form1 constructor:
public Form1()
{
InitializeComponent();
groupBox1.Validating += GroupBox1_Validating;
}
Sometimes when validating like this, you need to prevent the validation logic from executing if the user clicks the Cancel button. You're supposed to be able to set the CausesValidation property of the Cancel button to false to prevent this, but I find that it doesn't work for me.
Instead, I just use a bool cancelling field which I set to true in the Cancel button handler:
private void cancelButton_Click(object sender, EventArgs e)
{
cancelling = true;
this.Close();
}
bool cancelling;
And then add the following to the start of GroupBox1_Validating():
if (cancelling)
return;
If it is possible to have different UI design then my suggestion goes as under:
Alternative UI Design - A
Create One ListBox ListFieldsOriginal and populate
Create Second ListBox ListUserSelection, keep it empty initially
Provide buttons as under:
Button '>' means add currently selected item from ListFieldsOrginial to ListUserSelection at end; and remove that item from ListFieldsOriginal
Button '<' means remove currenly selected item from lstUserSelection; and add that item back to ListFieldsOriginal (of course at end)
NOTE: If adding item back to ListFieldsOriginal is your requirement then extra coding is required to find its appropriate index in the ListFieldsOriginal.
Alternative UI Design - B
Create One CheckedListBox ListFieldsOriginal and populate
Create one ListBox ListUserSelection, keep it empty initially
Define ItemCheck event handler for ListFieldsOriginal to add/remove items to/from ListUserSelected.
if (e.CurrentValue==CheckState.Unchecked)
{
string item = ListFieldsOriginal.Items[item];
ListUserSelection.Items.Add(item);
}
else
{
string item = ListFieldsOriginal.Items[item];
ListUserSelection.Items.Remove(item);
}
In the UI I'm working with, in a DataGrid, there are cases where the user might select a different row, but after a dialog interaction, the old row needs to be shown as being selected once again. If I simply try
BundleQueueDG.SelectedIndex = currentBundleIndex;
that does not do anything and in fact, once the SelectionChanged method exits, it changes to the new value. What is the best way to "re-select" the previously-selected row?
Try setting the SelectedItem property. Preserve what was selected before and set the SelectedItem with what was previously selected in your event.
Something like this:
private void DgDataGrid_OnSelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
{
int newIndex = (sender as DataGrid).SelectedIndex / 2;
if (Convert.ToInt32(newIndex) >= 1)
(sender as DataGrid).SelectedItem = previous;
else
{
previous = (sender as DataGrid).CurrentItem;
}
}
I have a combo box and want to add a key down function so that when Delete pressed then it will delete the Item in the combo box and sends a null value to the database:
private void comboBox_KeyDown(object sender, KeyEventArgs e)
{
ComboBox cmbx = (ComboBox)sender;
if (e.KeyCode == Keys.Delete)
{
cmbx.SelectedIndex = -1;
cmbx.SelectedValue = DBNull.Value;
}
}
But it's not working properly. Any suggestions
Your code doesn't really make any sense.
cmbx.SelectedIndex = -1; removes the selection that from the combo box, it doesn't remove the selected item.
Here's a few different methods of removing specific elements of your combobox.
// To remove item with index 0:
cmbx.Items.RemoveAt(0);
// To remove currently selected item:
cmbx.Items.Remove(cmbx.SelectedItem);
// To remove "Value1" item:
cmbx.Items.Remove("Value1");
Reference: http://msdn.microsoft.com/en-us/library/19fc31ss.aspx
I'm trying to remove selected item from ComboBox Collection:
I wrote a buttonClick:
cb01.Items.Remove(cb01.SelectedItem);.
This deletes the item, but next time I open the Form - the item appears again.
Please help.
Add KeyDown event for your ComboBox and then
private void cb01_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete)
{
if(cb01.SelectedIndex != -1)
cb01.Items.Remove(cb01.SelectedItem);
}
}
Above will remove items from comboBox but if you add items on designed time when you load the application again you can see all the items again.
check your InitializeComponent() method. you can see something like below.
this.cb01.Items.AddRange(new object[] {
"item1",
"item2",
"item13"});
when you load the application again, it will call InitializeComponent and call above method to add items.
To avoid this issue. You can use bound data source. e.g you can take items from database. and when you delete you can delete it from database. next time you load the application it only show the items in the database.
How about
if(cb01.SelectedItem != null)
cb01.Items.Remove(cb01.SelectedItem);
Why i did checking?
Since in last line you said
cb01.Items.RemoveAt(cb01.SelectedIndex); // error: Value of '-1' is not valid...
-1 is the index of combo when no item is selected. So i checked for selected item first. If found will go in if statement.
Replace comboBox1 with the name of your combobox and bind its KeyDown event
void comboBox1_KeyDown(object sender, KeyEventArgs e)
{
int currentItem = comboBox1.SelectedIndex;
if (e.KeyCode == Keys.Delete && currentItem != -1)
{
comboBox1.Items.RemoveAt(currentItem);
if (comboBox1.Items.Count > 0)
comboBox1.SelectedIndex = (currentItem > 0 ? currentItem - 1 : currentItem);
}
}
This will select the next item in list after removing it, or do nothing if there are either no items in the comboBox or no item is selected.