I have a string that separated by comma like this:
"test1,test2,test3"
and i want to convert those string to list with folowing code :
private void convertToList()
{
try{
List<string> myList = occ.Split(',').ToList();
listBox1.Items.Add(myList);
}catch(Exception e){
MessageBox.Show(e.Message);
}
}
I think that code will convert the string into a list and add it into a Listbox, instead, it shows only "collection"(yes only show the word "collection", nothing more) not the actual list.
why that's happened? can you tell me what's the right code?
Well, Add adds a single item which is a List<string> in your case. What should ListBox show for this? Collection seems to be a good enough solution. If you want to add entire collection in one go, try AddRange:
listBox1.Items.AddRange(occ.Split(','));
If you insist on Add, you have to loop in order to Add each item of the collection:
// To stop unwanted redrawing after each item addition
listBox1.BeginUpdate();
try {
foreach (var item in occ.Split(','))
listBox1.Items.Add(item);
}
finally {
listBox1.EndUpdate();
}
Related
I am unable to filter listbox data using linq and textbox.Listbox values don 't change when I enter text to be filtered inside the textbox. This function is important so that I can send the data to another form which contains the listbox.
public void GetList(List<SemesterDetails> modules)
{
string filter = txtFilter.Text;
foreach (var item in modules.Where(m => m.ModuleName.Contains(filter)))
{
LstModules.Items.Add(item);
}
}
I tried to call the function to the textbox event function:
private void txtFilter_TextChanged(object sender, TextChangedEventArgs e)
{
List<SemesterDetails> semesters = new List<SemesterDetails>();
GetList(semesters);
}
The result is:
Items remain unfiltered in the listbox.
List<SemesterDetails> semesters = new List<SemesterDetails>();
GetList(semesters);
This is an empty list.
public void GetList(List<SemesterDetails> modules)
{
string filter = txtFilter.Text;
foreach (var item in modules.Where(m => m.ModuleName.Contains(filter)))
{
LstModules.Items.Add(item);
}
}
Since you're passing in an empty list, the foreach will be executed 0 times, and therefore nothing can ever be added.
The filtering is irrelevant in this scenario.
Items remain unfiltered in the listbox
Nowhere in your code do you ever remove the items that are already in the listbox. Therefore, it's not possible for the listbox' contents to reduce.
When I add clear Listbox prior, I get no items
If you clear a list and then not add items to it (as discussed above), an empty list is indeed the logical outcome.
I try to add strings that are in a string array to an ObservableCollection.
The way i do it is:
In my constructor i instantiate the collection and add the eventhandler to call my method that adds the strings from the array to the list:
public CLoggerViewModel()
{
this._currenLogContent = new ObservableCollection<string>();
this._memoryAppender.LogContentChanged += new LoggingEventHandler(OnLogContentChanged);
}
In the eventhandler i want to iterate through the string array and add each string to the collection:
public void OnLogContentChanged(object sender, LoggingEventArgs e)
{
string[] tmpString = { "A", "B", "C", "D" };
foreach (string s in tmpString)
{
_currenLogContent.Add(s);
}
}
In my Argument
e.LogEntries
which holds my string array i have always all the strings that i expect.
For simplicity/test i dont use the array that i get from my argument and instantiate it with A,B,C,D , since i was asked to change it in way that it can be verified here.
My problem is that always just the first string of the array will be added to my ObservableCollection.
Once the first string is added it seems that my foreach iteration gets terminated.
EDIT:
In my WPF XAML file if have the following list box where my ObservableCollection is bound to:
<ListBox Name="listViewLog" ItemsSource="{Binding LoggerViewModel.CurrentLogContent,UpdateSourceTrigger=PropertyChanged}" Margin="0,0,-248,-377" Grid.ColumnSpan="2" RenderTransformOrigin="0.586,0.51" Height="367" VerticalAlignment="Bottom" />
If i remove the listbox with the binding to my Observablecollection it iterates through the foreachloop. So the listbox or the binding from the listbox to my collection is causing the stop of the iteration. I already tried to use all the UpdateSourceTrigger options (Default,Explicit,LostFocus,PropertyChanged).
But in all cases it stops the iteration after the first round.
Is there anything else that i have to set in the ListBox properties to avoid stopping to add strings to the Observablecollection?
EDIT:
The only solution i found that works for me is to Wrap the strings that i want to add to the collection in a separate class and adding the objects to the list. In this case it does not break my foreach loop if i add objects to the list.
public void OnLogContentChanged(object sender, LoggingEventArgs e)
{
string[] tmpString = { "A", "B", "C", "D" };
foreach (string s in tmpString)
{
this.LogEntries.Add(new CLogEntry(s));
}
}
CLogEntry is just a Wrapper that exposes a single string.
With this workaround it works, but still, i cant understand why it does not work if i "directly" add a string to the Observablecollection.
Have you set up another Data Binding to your ObservableCollection? Or have you set up Control to Control Data Binding to your ListBox? As your code seems to be right and I can not reproduce the problem, I think there is a data bounded "logic" triggered by the ObservableCollection cases an error - this error prevent the iteration to be completed.
IList<object> itemsSelected = MyGrid.SelectedItems;
foreach (object itemSelected in itemsSelected)
{
MyGrid.SelectedItems.Remove(itemSelected);
}
I try remove selected items from a GridView but not all selected items are removed.
Could someone help me?
object[] itemsSelected = MyGrid.SelectedItems.ToArray<object>();
foreach (object item in itemsSelected)
{
MyGrid.Items.Remove(item);
}
I had the exact problem as well. I wrote something like this but it didn't delete all items too, just some of them :
foreach(var item in MyGridView.SelectedItems)
{
MyGridView.Items.Remove(item);
}
But write this which will delete all your selected items for sure :
while (YourGridView.SelectedItems.Count != 0)
{
YourGridView.Items.Remove(YouGridView.SelectedItem);
}
there isn't exception, when you use foreach with SelectedItems? When you remove item, SelectedItems array is modified and foreach throws an exception. (Though I've tried on ListBox control). Try to use for-operator and remove items from last to first by index.
Based on your answers in the comments, I assume you are working on a C# winforms application.
Is it possible that what you are actualy using is a ListBox and not a GridView?
If that is so, you should use the ClearSelected() method which unselects all items in the ListBox.
how can i remove multiple items from observablecollection in silverlight.in my project i have one datagrid populating more than one items.in every row contain one checkbox also.if i select more than one row by selecting checkbox and click delete button ,i want to delete all the item from the collection.
public void delete(object parameter)
{
foreach (var x in Book)
{
if (x.Ischeck == true)
{
Book.Remove(x);
}
}
}
it cause error.can't change observablecollection
You can use below mentioned code snippet instead:
foreach (var x in Book.ToList())
{
if (x.Ischeck)
{
Book.Remove(x);
}
}
OR
for (int i = Book.Count - 1; i >= 0; i--)
{
if (Book[i].Ischeck)
{
Book.RemoveAt(i);
}
}
I assume that the error message is a bit different. To be more precise, it is:
Collection was modified; enumeration operation may not execute.
To work around this problem, one possible solution is this:
foreach (var itemToRemove in Book.Where(x => x.Ischeck).ToList())
{
Book.Remove(itemToRemove);
}
This will get all items you want to remove and put them into a new list. When you now remove items from Book you are not disturbing the list you are currently iterating over as this is an independent instance.
Using Where before calling ToList reduces the number of references you copy to the new list to only those that really need to be copied.
Simply get a list of the objects contained first:
public void delete(object parameter)
{
foreach (var x in Book.ToList())
{
if (x.Ischeck == true)
{
Book.Remove(x);
}
}
}
The reason for this is that you can't remove elements from an observable collection while you're enumerating the elements. By calling ToList() you enumerate the whole collection first, store it in a list and then check what to remove.
I have an Array List to save selected files and a ListBox to display only the name of the files..my requirement is to delete corresponding files from arraylist when its deleted from listbox...here is my code:
public ArrayList to_compress = new ArrayList();
ListBox pack_lbx=new ListBox();
private void add_btn_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Multiselect = true;
if (ofd.ShowDialog() == DialogResult.OK)
{
foreach (string f in ofd.FileNames)
{
FileInfo f_inf = new FileInfo(f);
if (pack_lbx.Items.IndexOf(Path.GetFileName(f)) == -1)
{
to_compress.Add(new string[] { f, f_inf.Name });
pack_lbx.Items.Add(Path.GetFileName(f));
}
}
}
private void remove_btn_Click(object sender, EventArgs e)
{
// pack_lbx.Items.Remove(pack_lbx.Items);
ListBox.SelectedObjectCollection s = pack_lbx.SelectedItems;
while (s.Count > 0)
{
pack_lbx.Items.Remove(s[0]);
to_compress.Remove(s.ToString()); //this doesnt work
}
}
I don't see a question here. I'm assuming that you're getting an error because you're trying to modify a collection that you're actively looping through?
If that's NOT the issue, please change this to a question so that we can give a better answer.
However, assuming I am guessing right...
You can't do that... It messes up things if you alter the list you're looping through.
Instead, you should be creating a NEW list and adding items to it (copying them from the list you're looping through as you're looping through it) and just skipping the "add" code for the items you want to "delete".
while (s.Count > 0)
{
pack_lbx.Items.Remove(s[0]);
to_compress.Remove(s.ToString());//this doesnt work
}
this will not work because , you are deleting object from a collection while looping through the collection so
do this
private void remove_btn_Click(object sender, EventArgs e)
{
// pack_lbx.Items.Remove(pack_lbx.Items);
ArrayList tempList = new ArrayList();
ListBox.SelectedObjectCollection s = pack_lbx.SelectedItems;
foreach(string str in to_compress)
{
if(!s.Contains(str))
tempList.Add(str)
}
to_compress = tempList;
}
Trying to keep two identical lists synchronised is a pattern that opens you up to bugs, because if you fail to synchronise correctly in just one place, your UI will be displaying information that is different from what your program is using internally.
A better approach is to only keep one "master" list. Let the ListBox hold the list, manipulate it in the ListBox, and only copy the filenames out of the ListBox at the end of the process.
If you want the text displayed in the listbox to be different from the underlying string (e.g. display leafnames in the box but keep full pathnames internally) then you can create a trivial class to hold the full pathname and override its ToString() to return the leafname. Then add instances of this class rather than raw strings to the ListBox.
If you insist on keeping two lists in sync, then the easiest is to use ListBox.SelectedIndex with the RemoveAt() method, and simply remove the same item from both lists.
If you need to remove an item from a list that you are enumerating, you can either:
Use a for loop with an index instead of foreach to do the iterating. You can then acess list items with the array index [i] syntax, and delete them with RemoveAt(i). Just be careful with how you advance the index after deleting an item.
Use a separate variable/list to store references to the items you wish to delete during your first loop, and then execute a second loop over this list to actually do the deletion as a post-processing step.
to_compress.Remove(s[0].ToString());
I can't see any line of code that add the files to the ArrayList to_compress.
Also if you adding the FileInfo object to arraylist you can't remove it using the name of the file.
Consider using generic dictionary that have name of file as key and the actual file object as value.
var to_compress = new Dictionary<string,FileInfo>();
to_compress.Add(filename,File);
//then you can remove by
to_compress.Remove(filename);
//you can loop through it like so
foreach (var pair in to_compress)
{
string filename = pair.Key;
FileInfo file = pair.Value;
}