Listbox deselect top item - c#

I have a listbox and I want to deselect the first selected item in the list when the loop is run because it should process a list item after item. Currently I'm using this:
var list = new object[listBoxTracks.SelectedItems.Count];
for (int i = 1; i < listBoxTracks.SelectedItems.Count; i++)
list[i - 1] = listBoxTracks.SelectedItems[i];
listBoxTracks.SelectedItems.Clear();
foreach (var track in list)
listBoxTracks.SelectedItems.Add(track);
I think/know that this is probably very bad but I have no idea what other possibilities there are. I tried stuff with selectedIndex += 1 etc but that seems to crash it. If this has been answered before I'm sorry but I haven't found anything in my research :/

As far as I see, you can directly manipulate the SelectedItems. So you can also remove a single item from it, e.g.
listBoxTracks.SelectedItems.Remove(listBoxTracks.SelectedItems[0]);

private void checkedListBox1_SelectedValueChanged(object sender, EventArgs e)
{
checkedListBox1.SetItemChecked(checkedListBox1.SelectedIndex, true);
}
private void checkedListBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
checkedListBox1.SetItemChecked(checkedListBox1.SelectedIndex, true);
}
This Will Do It for Sure , wanted this for me as well...

Related

C# ListView prevent selection

I'm in a situation with a multiple select ListView where a maximum of three items may be selected. I currently have following code
private void grassListView_SelectedIndexChanged(object sender, EventArgs e)
{
string landType = this.grassLandTypeComboBox.Text;
if (this.grassListView.SelectedIndices.Count < 4)
{
ArrayList selectedGrassTextures = (ArrayList)((Hashtable)this.paintGrass[landType])["textures"];
selectedGrassTextures.Clear();
foreach (ListViewItem listViewItem in this.grassListView.SelectedItems)
{
selectedGrassTextures.Add(listViewItem.Text);
}
}
else
{
MessageBox.Show("You cannot have more than 3 grasses selected for any given attribute type");
}
}
this code works and in the end my selectedGrassTextures HashTable has only three elements. However the GUI still shows the element as (selected/focused?). So to the user it seems that it is still selected. So I like to prevent this, is there anything I can use to either find the last element clicked on and put the selection of it or the focus. Another way would be if there is an event Before SelectedIndexChanged that I can move my < 4 check into. Is there such an event, I thought ListView.SelectedIndexChanging, but in my IDE it shows up as not existing. I'm using visual studio express and framework 3.5, can't use 4.5 for what I'm doing.
Put this in the ItemSelectionChanged event:
private void listView1_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
if (listView1.SelectedItems.Count > 4) e.Item.Selected = false;
}

how to Combobox get a data in notepad (run time) by mouse click?

I making a complete INTERNET explorer. I have done many option, a bookmark create a problem. Suppose I get a value by click new value from the notepad file, when done this according my idea. One problem is again faced me , every click get a duplicate value. how to avoid a duplicate data please guide me.
My coding part is :-
private void comboBox1_SelectedIndexChanged_1(object sender, EventArgs e)
{
int kkk = comboBox1.Items.Count;
string path = File.ReadAllText("F:\\kmm.txt");
string[] y = path.Split('\n');
foreach (string kk in y)
{
comboBox1.Items.Add(kk);
}
// comboBox1.Items.Clear();
string km = comboBox1.SelectedItem.ToString();
wb.Navigate(km);
}
snap shot combobox::
Each time the ComboBox Selection Index is changed, Items are loaded from F:\kmm.txt.
You are applying a very wrong logic to load items in ComboBox
A better way would be load the item only once in the ComboBox in Form_Load event.
But in case you want the Add items to the ComboBox in comboBox1_SelectedIndexChanged_1 event you need to clear the items in comboBox1 .
Try this way :
private void comboBox1_SelectedIndexChanged_1(object sender, EventArgs e)
{
int kkk = comboBox1.Items.Count;
string path = File.ReadAllText("F:\\kmm.txt");
string[] y = path.Split('\n');
// clear all existing items first
comboBox1.Items.Clear();
foreach (string kk in y)
{
comboBox1.Items.Add(kk);
}
// comboBox1.Items.Clear();
string km = comboBox1.SelectedItem.ToString();
wb.Navigate(km);
}

ListView do not autoscroll to selected item if its position changed

I have a ListView with about 100 items. I have some item selected from past and now I need to scroll down to find another item, but in that time - refresh occurs and it just automatically scroll back to last selected item.
Is there any possibility how can I turn it off or better dont scroll if I'm currently scrolling?
Thanks for responds :)
I don’t know if this will help but here the settings that do NOT have the issue with scrolling back to the selected item when a new item is added and sorted. However, I use the sort setting and do not call sort or refresh.
Create a new form and place ListView and a Timer on there. On the ListView change ONLY these properties.
Set View to Details
Click Columns add a single Column (Adjust the width to make it wider)
Set Sorting to Ascending
Set the timer Enabled to true
Set interval to 2000 (2 secs)
Double click the Tick event to create a handler
Now add the following code
public Form1()
{
InitializeComponent();
for (int x = 0; x < 100; x++)
{
listView1.Items.Add("Item #" + x);
}
}
private int y = 10;
private void timer1_Tick(object sender, EventArgs e)
{
listView1.Items.Add("Item #" + y + "b");
y += 10;
}
Now when you run this you can select any item and scroll anywhere and it will not jump back to the selected item when a new item is added. However, it will scroll down one line if the item it adds is above …
Perhaps this gets you close enough that you can play with it further to get what you need.
But that is the best I could do w/o getting into sub-classing the ListView Control using the Win32 API somehow.
This is kind of a roundabout solution (and probably a little late), but it seems to work.
I'm using EnsureVisible() on the most recent added item to have auto-scrolling happen, which is called within the timer1_Tick method. But I'm using an "inspectingList" flag that will keep auto-scrolling from happening when you click on a list item. When focus moves away from the listview, scrolling continues as normal.
Part of the solution is what jross said to do, which is create a dummy form to test with:
private void Form1_Load(object sender, EventArgs e)
{
listView1.Columns.Add("Scroll Control", 100);
for(int i = 0; i < 100; i++)
{
listView1.Items.Add(string.Format("Item #{0:000}", i));
}
timer1.Interval = 1000;
timer1.Start();
}
private int newItem = 10;
private bool inspectingList = false;
private void timer1_Tick(object sender, EventArgs e)
{
listView1.Items.Add(string.Format("Item #{0:000}", newItem));
newItem += 10;
if (!inspectingList)
{
listView1.Items[listView1.Items.Count - 1].EnsureVisible();
}
listView1.Refresh();
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
inspectingList = true;
if (listView1.SelectedIndices.Count > 0)
{
listView1.Items[listView1.SelectedIndices[0]].EnsureVisible();
}
}
private void listView1_Leave(object sender, EventArgs e)
{
inspectingList = false;
}

update a list after deleting an item

i have a form that when i add a item it stores it within a list and adds it to a checklistbox
i have a button that deletes the item from the checklist box, but how would i get it so that when i delete it from the checklistbox it also deletes it within the list its been stored in
here is the code for the delete button
private void btnDelete_Click(object sender, EventArgs e)
{
for (int i = clbSummary.CheckedIndices.Count - 1; i >= 0; --i)
{
clbSummary.Items.RemoveAt(clbSummary.CheckedIndices[i]);
}
}
Why don't you do remove the item from the list within the btnDelete_Click method.
For example:
private void btnDelete_Click(object sender, EventArgs e)
{
for (int i = clbSummary.CheckedIndices.Count - 1; i >= 0; --i)
{
object item = clbSummary.Items[clbSummary.CheckedIndices[i]];
myList = myList.Remove(item);
clbSummary.Items.RemoveAt(clbSummary.CheckedIndices[i]);
}
}
I'm not sure if you can use the [] operator on Items, but this is to give you a general idea.
Set the checklistbox DataSource property to the list where you are storing the items. When you make any changes to the list, your checklistbox will update.

Collection was modified; enumeration may not execute error when removing a ListItem from a LIstBox

I have two ListBoxes, lstAvailableColors and lstSelectedColors. Between each listbox are two buttons, Add and Remove. When a color or colors is selected in lstAvailableColors and the Add button is clicked, I want to remove them from lstAvailableColors and display them in lstSelectedColors. Also, if colors are selected in lstSelectedColors and the Remove button is clicked, I want to remove the colors from lstSelectedColors and add them back to lstAvailableColors. When I do this, I get the following error when it removes the item:
Collection was modified; enumeration operation may not execute.
Here is the code for the Add Button and the Remove Button:
Add:
protected void btnAdd_Click(object sender, EventArgs e)
{
foreach (ListItem item in lstAvailableColors.Items)
{
if (item.Selected)
{
lstSelectedColors.Items.Add(item);
lstAvailableColors.Items.Remove(item);
}
}
}
Remove:
protected void btnRemove_Click(object sender, EventArgs e)
{
foreach (ListItem item in lstSelectedColors.Items)
{
if (item.Selected)
{
lstAvailableColors.Items.Add(item);
lstSelectedColors.Items.Remove(item);
}
}
}
It's not possible to modify a collection while you're enumerating it in .Net. You need to separate out your enumeration and remove code into different blocks. Here is a quick sample on how to do that in without LINQ
protected void btnAdd_Click(object sender, EventArgs e)
{
var selected = new List<ListItem>();
foreach (ListItem item in lstAvailableColors.Items)
{
if (item.Selected)
{
selected.Add(item);
lstSelectedColors.Items.Add(item);
}
}
foreach (ListItem item in selected)
{
lstAvailableColors.Items.Remove(item);
}
}
And here's a more concise version using LINQ
var selected = lstAvailableColors.Cast<ListItem>().Where(i => i.Selected).ToList();
selected.ForEach( x => { lstSelectedColors.Items.Add(x); });
selected.ForEach( x => { lstAvailableColors.Items.Remove(x);});
EDIT
The LINQ version works in two parts. The first part is the first line which finds the currently selected items and stores the value in a List<ListItem>. It's very important that the line contain the .ToList() call because that forces the query to execute immediately vs. being delayed executed.
The next two lines iterate through each value which is selected and remove or add it to the appropriate list. Because the selected list is already stored we are no longer enumerating the collection when we modify it.
You cannot modify an collection while you are using an Enumerator for this collection, what the for each statement does.
You have to loop over the data with a normal for loop and then you can modify the collection, but you must be careful to correctly update the current index if you insert or remove elements. If you just add or remove elements and don't insert some, iterating from the last element to the first will do.
protected void btnAdd_Click(object sender, EventArgs e)
{
for (Int32 i = lstAvailableColors.Items.Count; i >= 0; i--)
{
ListItem item = lstAvailableColors.Items[i];
if (item.Selected)
{
lstSelectedColors.Items.Add(item);
lstAvailableColors.Items.Remove(item);
}
}
}
You cannot modify a collection you are iterating on. In general, a good solution for this type of problem is to create an empty collection, and in your iterator, copy over all of the elements you do NOT want to remove; after the iteration is complete, replace the original collection with your new collection.
As the other answer mentioned, you can't remove items until you've completed the iteration. So perhaps something like this will be cleanest for you:
var itemsToRemove =
lstAvailableColors.Items.Cast<ListItem>().Where(i => i.IsSelected).ToArray();
foreach(ListItem item in itemsToRemove) lstAvailableColors.Remove(item);
You can't modify a collection while you're iterating over it. Either iterate over a copy or use for, iterate in reverse and remove as you go down.
Example on how to remove the selected Items. Here only the selected indices are taken and removed.
public void RemoveSelectedItems(ListBox listbox)
{
List<ListItem> items = GetSelectedItems(listbox);
foreach (var listItem in items)
{
listbox.Items.Remove(listItem);
}
}
public List<ListItem> GetSelectedItems(ListBox listbox)
{
int[] selectedIndices = listbox.GetSelectedIndices();
return selectedIndices.Select(index => listbox.Items[index]).ToList();
}
Maybe this is what you need
protected void btnAdd_Click(object sender, EventArgs e)
{
while(listBox1.SelectedIndex!=-1)
{
listBox1.Items.Remove(listBox1.SelectedItem);
}
}
This might help you;
To Remove:
protected void btnRemove_Click(object sender, EventArgs e)
{
{
for (int i = 0; i < lstAvailableColors.Items.Count; i++)
{
if(lstAvailableColors.Items[i].Selected)
lstAvailableColors.Items.RemoveAt(i);
}
}
}
The problem you face is that you can't modify the collection you itterate thru. You could solve this by using a single linq:
protected void btnAdd_Click(object sender, EventArgs e)
{
lstAvailableColors.Items.RemoveAll(ac => ac.Selected);
}
You can use this generic function to remove mulitple items form ObservableCollection ( I know that many are scared of Exceptions, but Exception is nothing but a dev tool)
public static void OCRemoveMultiple<T>(ref ObservableCollection<T> inputList, IList<T> toRemoveItems)
{
REITERATE:
{
try
{
while( inputList.Intersect<T>(toRemoveItems).Any())
{
var intersectionList = inputList.Intersect<T>(toRemoveItems);
foreach (var item in intersectionList)
{
inputList.Remove(item);
}
}
}
catch (Exception)
{
goto REITERATE;
}
}
}
Here is a test case (an example) how you can use it:
ObservableCollection<object> targetList = new ObservableCollection<object>();
targetList.Add("T1");
targetList.Add("T2");
targetList.Add("B3");
targetList.Add("B4");
targetList.Add("T5");
IList<object> toRemove = targetList.ToList().Where(k=>k.ToString().Contains("B")).ToList();
OCRemoveMultiple(ref targetList, toRemove);
targetList.ToList().ForEach(k => Console.WriteLine(k.ToString())); // Writes "T1", "T2" and "T5"

Categories

Resources