How to convert listbox.items to a Array - c#

I'm making a search function for a ListBox, and I would like that as soon as the user types something into a TextBox, all items are removed from the ListBox except the item that matches the search text.
//files[i] are the files of the openfiledialog
List<String> ListboxItems = new List<String> {files[i]};
try
{
String search = gunaTextBox1.Text;
if (String.IsNullOrEmpty(search))
{
listBox1.Items.Clear();
listBox1.Items.AddRange(ListboxItems.ToArray());
}
var items = (from a in ListboxItems
where a.StartsWith(search)
select a).ToArray<String>();
listBox1.Items.Clear();
listBox1.Items.AddRange(items);
}
catch { }
Does anyone know how I can implement this?

Here is the solution
first you need to add a List String List<string> listcollection = new List<string>();
then you need to write the Textbox1_TextChanged event
List<string> listcollection = new List<string>();
private void gunaTextBox1_TextChanged(object sender, EventArgs e)
{
if(gunaTextBox1.Text == "Suche")
{
}
else
{
try
{
String search = gunaTextBox1.Text;
if (String.IsNullOrEmpty(search))
{
listBox1.Items.Clear();
listBox1.Items.AddRange(listcollection.ToArray());
}
var items = (from a in listcollection
where a.IndexOf(search, StringComparison.OrdinalIgnoreCase) > -1
select a).ToArray<String>();
listBox1.Items.Clear();
listBox1.Items.AddRange(items);
}
catch
{
}
}
}
and then just link it up
listcollection.Clear();
foreach(string str in listBox1.Items)
{
listcollection.Add(str);
}

Related

List doesn't filter properly using Contains in combobox

I am trying to come up with a solution where I can search items inside a combo box that contain certain word/phrase. I tried using the AutoComplete text box functionality, but that only searches for the first word which is no good to me.
I have followed the example provided at https://social.msdn.microsoft.com/Forums/vstudio/en-US/4c229a73-cdad-4fa3-95db-97f9ff7810c1/autocomplete-match-on-contains-not-startswith?forum=netfxbcl
I have initiated 2 lists
public List<string> listOnit = new List<string>();
public List<string> listNew = new List<string>();
I then load the data into a comboBox
if (rdr.HasRows == true)
{
// var source = new List<string>();
while (rdr.Read())
{
// myCollectionSales.Add(rdr[0].ToString());
listOnit.Add(rdr[0].ToString());
}
rdr.Close();
//textBox1.AutoCompleteCustomSource = myCollectionSales;
comboBox1.Items.AddRange(listOnit.ToArray());
}
and have a TextUpdate event handler to filter the list when text has changed
private void comboBox1_TextUpdate(object sender, EventArgs e)
{
comboBox1.Items.Clear();
listNew.Clear();
foreach (var item in listOnit)
{
if (item.Contains(this.comboBox1.Text))
{
listNew.Add(item);
}
}
comboBox1.Items.AddRange(listNew.ToArray());
comboBox1.SelectionStart = this.comboBox1.Text.Length;
Cursor = Cursors.Default;
comboBox1.DroppedDown = true;
}
I am coming across a problem where the search results don't return what I expect. For example, I search for the string "Bud" and I only get the following results
http://prntscr.com/ppkatd
While in the database, there is also Budweiser 33cl and Keg Budweiser (http://prntscr.com/ppkbu4), for example, which is fetched on the first list.
Should I be using a different method, rather than "Contains"?
Perhaps you are using different cases?
Try with .ToLower():
private void comboBox1_TextUpdate(object sender, EventArgs e)
{
comboBox1.Items.Clear();
listNew.Clear();
foreach (var item in listOnit)
{
if (item.ToLower().Contains(this.comboBox1.Text.ToLower()))
{
listNew.Add(item);
}
}
comboBox1.Items.AddRange(listNew.ToArray());
comboBox1.SelectionStart = this.comboBox1.Text.Length;
Cursor = Cursors.Default;
comboBox1.DroppedDown = true;
}

search a textfile with a textbox

I have a textbox that I want to use to autosearch my text file and display the results in the listbox. the listbox already contains the first item of each line in the text file, so I basically want to search using only the first item of every line in the text file.
The code I currently have does nothing.
private void custsearchbox_TextChanged(object sender, EventArgs e)
{
string[] autosource = File.ReadAllLines(#"data\Suppliers.txt");
for (int g = 0; g < autosource.Length; g++)
{
custsearchbox.AutoCompleteCustomSource.Add(autosource[g]);
}
custsearchbox.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
}
I want to type the first item in my text box and search my listbox, as I enter my text I want the list to filter out the items that does not match. Please help me achieve this.
I tried this:
private void supsearchtxt_TextChanged(object sender, EventArgs e)
{
listsup.Items.Clear();
Supfile = System.AppDomain.CurrentDomain.BaseDirectory + "data\\Suppliers.txt";
List<string> proName = new List<string>();
using (StreamReader rdr = new StreamReader(Supfile))
{
string line;
while ((line = rdr.ReadLine()) != null)
{
if (line.Contains(supsearchtxt.Text))
{
string[] val = line.Split(',');
listsup.Items.Add(val[0]);
}
}
}
}
and it works great.

Why is multiple item drop not working on listbox?

I create a playlist for media player.
Follow my code:
Xaml:
<MediaElement x:Name="mePlayer" Margin="64,0,90,61" ></MediaElement>
<ListBox x:Name="listbox4" Background="Salmon" BorderBrush="Black" BorderThickness="3" Drop="listbox4_Drop" >
</ListBox>
<Button x:Name="load" Content="Load" HorizontalAlignment="Left" VerticalAlignment="Top" Width="76" Click="load_Click" Margin="184,285,0,0"/>
Xaml.cs:
private Dictionary<string, string> fileDictionary = new Dictionary<string, string>();
private void load_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
ofd.DefaultExt = ".mp3";
ofd.Filter = "All|*.*";
ofd.Multiselect = true;
Nullable<bool> result = ofd.ShowDialog();
if (result == true)
{
for (int i = 0; i < ofd.FileNames.Length; i++)
{
var filePath = ofd.FileNames[i];
var fileName = System.IO.Path.GetFileName(filePath);
fileDictionary.Add(fileName, filePath);
listbox4.Items.Add(fileName);
listbox4.SelectedItem = fileName;
}
}
}
private void listbox4_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] droppedFilePaths =
e.Data.GetData(DataFormats.FileDrop, true) as string[];
foreach (string droppedFilePath in droppedFilePaths)
{
for (int i = 0; i < droppedFilePaths.Length; i++)
{
var filePath = droppedFilePaths[i];
var fileName = System.IO.Path.GetFileName(filePath);
fileDictionary.Add(fileName, filePath);
listbox4.Items.Add(fileName);
listbox4.SelectedItem = fileName;
}
}
}
}
It's working single file drop but while I drop multiple file then it's not added on listbox.
Multiple loaded file is loaded but multiple file will not dropped.
How can I drop multiple file on listbox?
Since I am not able to replicate the problem you listed I currently can not help you in that regard. Though, I can help you where I see fit.
Your current Drop method has an extra loop that multiples the number of items you add to the listbox.
Your current method:
private void listbox4_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] droppedFilePaths =
e.Data.GetData(DataFormats.FileDrop, true) as string[];
foreach (string droppedFilePath in droppedFilePaths)
{
//if you keep this loop, you will all the dropped files for each dropped file
//therefore, if I dropped 3 files, I'd get 9 entries in the listbox
//if I dropped 4 files, I'd get 16 entries and so on...
for (int i = 0; i < droppedFilePaths.Length; i++)//this has to go
{//this has to go
var filePath = droppedFilePaths[i];//this needs to be a different variable since "i" will no longer exist
var fileName = System.IO.Path.GetFileName(filePath);
//fileDictionary.Add(fileName, filePath);
listbox4.Items.Add(fileName);
listbox4.SelectedItem = fileName;
}//this has to go
}
}
}
Refactored (using the ForEach)
private void blaze_125_listbox4_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] droppedFilePaths =
e.Data.GetData(DataFormats.FileDrop, true) as string[];
foreach (string droppedFilePath in droppedFilePaths)
{
var filePath = droppedFilePath;
var fileName = System.IO.Path.GetFileName(filePath);
//fileDictionary.Add(fileName, filePath);
listbox4.Items.Add(fileName);
listbox4.SelectedItem = fileName;
}
}
}
This would also work (using the ForLoop)
private void blaze_125_listbox4_Drop_anotherSpin(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] droppedFilePaths =
e.Data.GetData(DataFormats.FileDrop, true) as string[];
for (int i = 0; i < droppedFilePaths.Length; i++)
{
var filePath = droppedFilePaths[i];
var fileName = System.IO.Path.GetFileName(filePath);
//fileDictionary.Add(fileName, filePath);
listbox4.Items.Add(fileName);
listbox4.SelectedItem = fileName;
}
}
}
Slimmer
private void blaze_125_listbox4_Drop_Slimmer(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] droppedFilePaths =
e.Data.GetData(DataFormats.FileDrop, true) as string[];
foreach (string droppedFilePath in droppedFilePaths)
{
listbox4.Items.Add(System.IO.Path.GetFileName(droppedFilePath));
}
}
}
Using the dictionary to store items, and to update the list
Dictionary<string, string> fileDictionary = new Dictionary<string, string>();
private void blaze_125_listbox4_Drop_Slimmer(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] droppedFilePaths =
e.Data.GetData(DataFormats.FileDrop, true) as string[];
foreach (string droppedFilePath in droppedFilePaths)
{
//listbox4.Items.Add(System.IO.Path.GetFileName(droppedFilePath));//don't need this anymore
//Check if the file is already in the dictionary.
//Check by looking up the key, and by looking up the value too.
if (fileDictionary.ContainsKey(System.IO.Path.GetFileName(droppedFilePath)) || fileDictionary.ContainsValue(droppedFilePath))
{
//no need to add this file, it's already in the dictionary
//if you try to add a file with a KEY identical to a KEY that already exists in the dictionary,
//it will throw an exception
//A dictionary can contain the same value multiple times, but it can not contain the same key more than once.
}
else
{
//the file is not listed in the dictionary, so lets add it
fileDictionary.Add(System.IO.Path.GetFileName(droppedFilePath), droppedFilePath);
}
}
}
//Now lets call the method in charge of updating the listbox
UpdateTheListbox(fileDictionary, listbox4);
}
private void UpdateTheListbox(Dictionary<string, string> incomingDictionary, ListBox listboxToModify)
{
listboxToModify.Items.Clear();//clear all the items in the list
foreach (KeyValuePair<string, string> item in incomingDictionary)
{
listboxToModify.Items.Add(item.Key);
}
//this method should probably be optimized because if your listBox already contains a large number of items
//it may be quicker to only add the missing items, instead of reverting back to an empty list, and adding all the items to it again.
//Though I'll leave this up to you to implement. We'll be here to answer questions if you have a hard time doing it.
}
Updated method to maintain the selected item if there is a selected item
private void UpdateTheListboxMaintainExistingSelection(Dictionary<string, string> incomingDictionary, ListBox listboxToModify)
{
var preSelectedItem = listboxToModify.SelectedItem;//store the current selection
listboxToModify.Items.Clear();//clear all the items in the list
foreach (KeyValuePair<string, string> item in incomingDictionary)
{
listboxToModify.Items.Add(item.Key);
}
//this method should probably be optimized because if your listBox already contains a large number of items
//it may be quicker to only add the missing items, instead of reverting back to an empty list, and adding all the items to it again.
//Though I'll leave this up to you to implement. We'll be here to answer questions if you have a hard time doing it.
//Maintain the selected item if there was one
if (preSelectedItem != null)
{
listboxToModify.SelectedItem = preSelectedItem;
}
}
To maintain the selection or select the last item if there was no selection
private void UpdateTheListboxMaintainExistingOrSelectLastAdded(Dictionary<string, string> incomingDictionary, ListBox listboxToModify)
{
var preSelectedItem = listboxToModify.SelectedItem;//store the current selection
listboxToModify.Items.Clear();//clear all the items in the list
foreach (KeyValuePair<string, string> item in incomingDictionary)
{
listboxToModify.Items.Add(item.Key);
}
//this method should probably be optimized because if your listBox already contains a large number of items
//it may be quicker to only add the missing items, instead of reverting back to an empty list, and adding all the items to it again.
//Though I'll leave this up to you to implement. We'll be here to answer questions if you have a hard time doing it.
if (preSelectedItem != null)
{
//Maintain the selected item if there was one
listboxToModify.SelectedItem = preSelectedItem;
}
else
{
//select the last item in the listbox if nothing was pre-selected
listboxToModify.SelectedItem = listboxToModify.Items[listboxToModify.Items.Count - 1];
}
}

Trying to populate textbox and listview from txt file

I'm able to save the textbox text and the listview items to a txt file properly by using:
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
if (saveFileDialog1.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
{
using (StreamWriter writer = new StreamWriter(saveFileDialog1.FileName))
{
//writer.WriteLine(accountText.Text);
writer.WriteLine(accountText.Text);
if (transactionList.Items.Count > 0)
{
foreach (ListViewItem item in transactionList.Items)
{
StringBuilder newString = new StringBuilder();
foreach (ListViewItem.ListViewSubItem listSub in item.SubItems)
{
newString.Append(string.Format("{0}\t", listSub.Text));
}
writer.WriteLine(newString.ToString());
}
writer.WriteLine();
}
}
}
}
However, I'm only able to load the textbox and can't seem to get the listview to populate. Here's what I have for that so far:
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
{
using (StreamReader reader = new StreamReader(openFileDialog1.FileName))
{
accountText.Text = reader.ReadLine();
if (transactionList.Items.Count == 0)
{
foreach (ListViewItem item in transactionList.Items)
{
StringBuilder myString = new StringBuilder();
foreach (ListViewItem.ListViewSubItem listSub in item.SubItems)
{
myString.Append(string.Format("{0}\t", listSub.Text));
}
reader.Read();
}
reader.ReadToEnd();
}
}
}
}
Any tips would be appreciated.
You just need to split string by '\t' character, it will return string[]. Then just add these array items to listview.
string[] items = reader.ReadLine().Split('\t');
foreach (var item in items)
{
var listViewItem = new ListViewItem(item);
transactionList.Items.Add(listViewItem);
}
As far as I can tell you're not putting the string into the ListView.
You will want to to do something like this:
foreach (ListViewItem.ListViewSubItem listSub in item.SubItems)
{
myString.Append(string.Format("{0}\t", listSub.Text));
listSub.Text = myString.ToString();
}
You need to reverse all your actions while reading
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
{
using (StreamReader reader = new StreamReader(openFileDialog1.FileName))
{
accountText.Text = reader.ReadLine();
while(!reader.EndOfStream)
{
var myString = reader.ReadLine();
var subitems = myString.Split("\t");
// Create ListItem and assign subItems here...
transactionList.Items.Add(new ListviewItem(subitems));
}
}
}
}
}

Listbox bindind from another listbox

i have two list boxes in my form and a button in between these two boxes. In the first box i binded some data from the database and from this list box i have to select the items and should display those selected items in the second list box. this should happen when i click a button.i used the following code.i used a hash table.
private void btnCATAdd_Click(object sender, EventArgs e)
{
Hashtable ht = new Hashtable();
ht.Add(lbCATallSubcat.SelectedValue.ToString(),
lbCATallSubcat.Text.ToString());
int i = 0;
foreach (string ent in ht.Values)
{
string[] name = new string[lbCATallSubcat.Items.Count];
for (i = 0; i < lbCATallSubcat.SelectedItems.Count; i++)
{
name[i] = lbCATallSubcat.Text;
this.lbCATSelectedSubcat.Items.Add(name[i]);
}
lbCATSelectedSubcat.DisplayMember = ht.Values.ToString();
lbCATSelectedSubcat.ValueMember = ht.Keys.ToString();
}
}
well its working fine when im selecting only single item in the first list box but im unable to display when more than one item is selectd from the first list box
You should use SelectedItems property on that listbox instead SelectedValue. Currently your Hashtable contains only one element.
See http://msdn.microsoft.com/en-us/library/system.windows.forms.listbox.selecteditems.aspx
Add all selected value in hashtable using loop
private void btnCATAdd_Click(object sender, EventArgs e)
{
Hashtable ht = new Hashtable();
for(int i=0;i<lbCATallSubcat.Items.Count;i++)
{
if(ht.items[i].Selected)
{
ht.Add(lbCATallSubcat.Items[i].Value.ToString(),
lbCATallSubcat.Items[i].Text.ToString());
}
}
i = 0;
foreach (string ent in ht.Values)
{
string[] name = new string[lbCATallSubcat.Items.Count];
for (i = 0; i < lbCATallSubcat.SelectedItems.Count; i++)
{
name[i] = lbCATallSubcat.Text;
this.lbCATSelectedSubcat.Items.Add(name[i]);
}
lbCATSelectedSubcat.DisplayMember = ht.Values.ToString();
lbCATSelectedSubcat.ValueMember = ht.Keys.ToString();
}
}
Do you need the Hashtable? With LINQ, you can do something like:
public ObjHoldingData
{
public Display { get; set; }
public Value { get; set; }
}
public class Form
{
Form()
{
var dataList = new List<ObjHoldingData>();
//TODO: Fill list with all the data you pulled
Listbox1.Datasource = dataList;
Listbox1.DisplayMember = "Display";
Listbox1.ValueMember = "Value";
}
protected void ButtonClick()
{
Listbox2.Datasource = Listbox1.SelectedItems.Cast<ObjHoldingData>().ToList();
Listbox2.DisplayMember = "Display";
Listbox2.ValueMember = "Value";
}
}
If you still need the Hashtable you can do this at the start of the button click:
var ht = new Hashtable(ListBox1.SelectedItems.Cast<ObjHoldingData>().ToDictionary(o => o.Display, o => o.Value));

Categories

Resources