0

This is a problem I am having in C# Visual studio 2019, and it should be relatively simple for somebody more experienced to help me, and I appreciate all help. I'm going crazy trying to figure this out! I have two listboxes, one called boyBox and one called GirlBox. I used to populate the listboxes with the text files:

private void populateBoys()
 {
            //Try to access the file, if problems arise an error message will show
            try
            {
                //Declare object to access file
                StreamReader inputFile;
                inputFile = File.OpenText("..\\..\\BoyNames.txt");

                //Loop to run through all items in the text file
                while (!inputFile.EndOfStream)
                {
                    //read lines from the file and add to the listbox
                    boyBox.Items.Add(inputFile.ReadLine());
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void populateGirls()
        {
            //Try to access the file, if problems arise an error message will show
            try
            {
                //Declare object to access file
                StreamReader inputFile;
                inputFile = File.OpenText("..\\..\\GirlNames.txt");

                //Loop to run through all items in the text file
                while (!inputFile.EndOfStream)
                {
                    //read lines from the file and add to the listbox
                    girlBox.Items.Add(inputFile.ReadLine());
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

To populate the listboxes with a list of popular boy and girl names called BoyNames.txt and GirlNames.txt. This seems simple enough, but I am being driven insane trying to find something that works for me to simply type a name into a textbox and have the program tell me if the name was in the list or not. The closest I got was :

private void boyButton_Click(object sender, EventArgs e)
{
    string boyname = boyBox2.Text;
    bool found = false;
    for(int n = 0; n < boyBox.Items.Count; n++)
    {
        if (boyBox.Items[n] == boyname)
        {
            found = true;
            break;
        }
    }

    if (found)
        MessageBox.Show("popular");
    else
        MessageBox.Show("not popular");

}

But it just says "Not Popular" even if I typed one of the names that IS in the list into the textbox "boyBox2". The listbox is "boyBox". I'm just trying to find help to figure out what code I can use to get it to work for letting me know if what I type into the textbox "boyBox2" is a name that is in the listbox/file or not. Thank you!

2 Answers2

0

The following reads a file with girl names into a BindingList<GirlName> which becomes the data source of a BindingSource which is set to a ListBox.

In a TextBox TextChanged event a lambda statement does a like/starts-with on names in the ListBox. If the TextBox is empty the filter is removed.

Containers for names

public class NameBase
{
    public int Index { get; set; }
    public string DisplayText { get; set; }
    public override string ToString() => DisplayText;
}

public class GirlName : NameBase { }
public class BoyName : NameBase { }

Classes for taking a raw text file with girl names to a sorted list of girl names in a new file.

public static class Extensions
{
    public static string ToTitleCase(this string sender) 
        => string.IsNullOrWhiteSpace(sender) ? 
            sender : 
            CultureInfo.InvariantCulture.TextInfo.ToTitleCase(sender.ToLower());
}

public class FileOperations
{

    public static string _fileName => "gNames.txt";
    public static bool GirlFileExits => File.Exists(_fileName);

    /// <summary>
    /// Used to create a list of names without extra data
    /// along with proper casing names
    /// </summary>
    public static void CreateGirlFile()
    {
        List<string> list = new List<string>();
        /*
         * girlnames.txt came from
         * https://github.com/SocialHarvest/harvester/blob/master/data/census-female-names.csv
         * populated via raw button, copied to girlnames.txt, set copy to output directory if newer
         */
        var names = File.ReadAllLines(_fileName);

        /*
         * assumes comma delimited with at least one item
         */
        foreach (var name in names)
        {
            string[] lineSplit = name.Split(',');
            list.Add(lineSplit[0].ToTitleCase());
        }

        list = list.OrderBy(item => item).ToList();

        File.WriteAllLines(_fileName, list.ToArray());
    }

    public static List<GirlName> ReadGirlNames()
    {
        List<GirlName> names = new List<GirlName>();

        var lines = File.ReadAllLines(_fileName);
        
        for (int index = 0; index < lines.Length -1; index++)
        {
            names.Add(new GirlName() {Index = index, DisplayText = lines[index]});
        }

        return names;
    }
}

Form has a ListBox and TextBox which does a starts-with, could also be a contains or ends-with.

public partial class Form1 : Form
{
    private readonly BindingSource _girlNamesBindingSource = new BindingSource();
    private BindingList<GirlName> _girlsNamesBindingList;  

    public Form1()
    {
        InitializeComponent();
        
        Shown += OnShown;
        SearchTextBox.TextChanged += SearchTextBoxOnTextChanged;
    }

    private void SearchTextBoxOnTextChanged(object sender, EventArgs e)
    {
        if (_girlNamesBindingSource == null) return;

        List<GirlName> filtered = _girlsNamesBindingList.Where(nameItem => 
            nameItem.DisplayText.StartsWith(
                SearchTextBox.Text, StringComparison.OrdinalIgnoreCase)).ToList();

        _girlNamesBindingSource.DataSource = filtered;

    }

    private void OnShown(object sender, EventArgs e)
    {
        if (!FileOperations.GirlFileExits)
        {
            FileOperations.CreateGirlFile();
        }
        
        _girlsNamesBindingList = new BindingList<GirlName>(FileOperations.ReadGirlNames());
        _girlNamesBindingSource.DataSource = _girlsNamesBindingList;
        GirlsNameListBox.DataSource = _girlNamesBindingSource;

    }
}

enter image description here

Karen Payne
  • 4,341
  • 2
  • 14
  • 31
0

Simply because you try to compare BETWEEN Item and string value and, you must compare BETWEEN the Item's value and the string value so, the code must be like so

private void boyButton_Click(object sender, EventArgs e)
{
    string boyname = boyBox2.Text;
    bool found = false;
    for(int n = 0; n < boyBox.Items.Count; n++)
    {
        if (boyBox.Items[n].Value == boyname)
        {
            found = true;
            break;
        }
    }

    if (found)
        MessageBox.Show("popular");
    else
        MessageBox.Show("not popular");

}

OR

You must convert the Item to string using ToString() method so, the code must be like so

private void boyButton_Click(object sender, EventArgs e)
{
    string boyname = boyBox2.Text;
    bool found = false;
    for(int n = 0; n < boyBox.Items.Count; n++)
    {
        if (boyBox.Items[n].ToString() == boyname)
        {
            found = true;
            break;
        }
    }

    if (found)
        MessageBox.Show("popular");
    else
        MessageBox.Show("not popular");

}

You can see this question also