简单但令人沮丧的列表框和文本框搜索

本文关键字:列表 文本 搜索 简单 | 更新日期: 2023-09-27 18:17:22

我花了几天时间到处寻找解决这个问题的方法。这是c#与Visual Studio 2013(是的,我是一个新手):

  • 两个文本框(姓氏和名字)和一个包含5个名字的列表框(Higgins M, Higgins J, King J, Tran a, Dempsey S)。
  • 如果我在列表框中选择了Higgins J,那么Higgins这个词应该出现在姓氏文本框中,J应该出现在名字文本框中。
  • 如果在"姓"文本框中输入Higgins,则列表框中选中的项为Higgins J (Higgins J会在Higgins M之前选中),如果在"名"文本框中输入M,则选中的项由Higgins J变为Higgins M。

但是…以下是促使我决定在这里创建一个帐户的问题:

  1. 如果我输入Hi或higg而不是Higgins,它必须保持这种方式,它不会在文本框中变成Higgins。只有列表框中的索引/高亮被更改,而不是文本框中的条目(我在文本框中键入的任何内容都保留)。我怀疑我使用的事件是我无法完成任务的原因。Textbox_textchanged和listbox_selectedindexchanged。所以无论我在一个事件中做什么都会自动触发另一个事件。我曾试图改变这些事件,但到目前为止,结果更糟。使用:if (LastName_textbox.)Text = ")也没用

  2. 如何将姓氏和名字合并为一个索引?

如果这个问题显得或听起来模棱两可,我很抱歉。我想我不知道如何表达搜索得到类似我的问题和英语不是我的第一语言。任何帮助都是非常感激的。谢谢。

以下是部分代码:

using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Project
{
public partial class frmContact : Form
{
    //declare file to save all contacts    
    private string fileName = Directory.GetCurrentDirectory() + "''Contacts.txt";
    //create temporary file for updating and deleting contacts        
    private string newContacts = Directory.GetCurrentDirectory() + "''newContacts.txt";
    public frmContact()
    {
        InitializeComponent();
    }
    private void frmContact_Load(object sender, EventArgs e)
    {
        //create Contacts.txt if it does not exist
        if (!File.Exists(fileName))
        {
            File.Create(fileName).Close();
            MessageBox.Show("New " + fileName +"  Has Been Created");
            tbLast.Select();
        }
        //if file already exists
        else
        {
            StreamReader readOb = new StreamReader(fileName);
            using (readOb)
            { 
                while (!readOb.EndOfStream)
                {
                    string rdLine = readOb.ReadLine(); //read data in file by line
                    string[] tmpArr = rdLine.Split(',');
                    lbContact.Items.Add(tmpArr[0] + "," + tmpArr[1]);
                }
                tbLast.Select();
            }
        }
    }
    private void lbContact_SelectedIndexChanged(object sender, EventArgs e)
    {
        //show details of contact selected in listbox
        string findNames = lbContact.GetItemText(lbContact.SelectedItem);
        StreamReader obRead = new StreamReader(fileName);
        using (obRead)
        {
            while (!obRead.EndOfStream)
            {
                string rdLine = obRead.ReadLine();
                if (rdLine.StartsWith(findNames))
                {
                    string[] tmpArr = rdLine.Split(',');
                    tbLast.Text = tmpArr[0];
                    tbFirst.Text = tmpArr[1].Trim();
                    tbAddr.Text = tmpArr[2].Trim();
                    tbSub.Text = tmpArr[3].Trim();
                    tbPost.Text = tmpArr[4].Trim();
                    tbEmail.Text = tmpArr[5].Trim();
                    tbPhone.Text = tmpArr[6].Trim();
                    tbMob.Text = tmpArr[7].Trim();
                }
            }
            lbContact.SelectedIndex = lbContact.FindString(findNames);
        }
    }
    private void tbLast_TextChanged(object sender, EventArgs e)
    {
        lbContact.SelectedItem = lbContact.FindString(tbLast.Text);
    }

简单但令人沮丧的列表框和文本框搜索

一个简单(但有点难看)的解决方案是使用一个布尔值通知您的lbContact_SelectedIndexChanged方法,索引由于代码而被手动更改。类成员将完成这项工作,例如:

private bool fromCode;
private void lbContact_SelectedIndexChanged(object sender, EventArgs e)
{
    if (fromCode)
       return;
    // Do the job
}
private void tbLast_TextChanged(object sender, EventArgs e)
{
    fromCode = true;
    lbContact.SetSelected(lbContact.FindString(tbLast.Text), true);
    fromCode = false;
}

(个人备注)我还将创建一个Contact结构体/类来存储您的信息以及表单中的集合,以便您只需要访问文件两次:

  • 加载时,以便您可以填充您的集合
  • 在关闭时,以便您可以保存更改到您的文件
(更新)

我的最后一句话可能不相关,因为我不知道您正在开发应用程序的背景,这就是为什么我说这是个人观点,您不必这样做。

(更新2)

如何避免每次调用lbContact_SelectedIndexChanged事件时访问文件:

  • 创建一个结构或类来存储您的联系人信息(名字,姓氏,地址,…)
  • 创建一个集合(作为窗体的类成员),它将包含联系人(如List<Contact>)
  • frmContact_Load方法中,用文件中包含的数据填充此集合,而不是填充列表框
  • 这样在你的lbContact_SelectedIndexChanged方法中你将在集合中搜索而不是打开你的文件
  • 你的Add()和Delete()操作也必须修改集合而不是文件
  • 请记住在应用程序关闭时将您的收集保存回您的文件

希望有帮助。

我找到了解决方案(对于遇到类似问题的人),答案在文本框中。聚焦:),并结合列表框。setselected from Tim.

    private void tbLast_TextChanged(object sender, EventArgs e)
    {
        if (tbLast.Focused && tbLast.Text != "")
        {
            if (lbContact.FindString(tbLast.Text) > -1)
            {
                lbContact.SetSelected(lbContact.FindString(tbLast.Text), true);
            }
        }
    }
    private void lbContact_SelectedIndexChanged(object sender, EventArgs e)
    {
        //show details of contact selected in listbox
        string findNames = lbContact.GetItemText(lbContact.SelectedItem);
        StreamReader obRead = new StreamReader(fileName);
        using (obRead)
        {
            while (!obRead.EndOfStream)
            {
                string rdLine = obRead.ReadLine();
                if (rdLine.StartsWith(findNames))
                {
                    string[] tmpArr = rdLine.Split(',');
                    if (!tbLast.Focused)
                    {
                        tbLast.Text = tmpArr[0];
                        tbFirst.Text = tmpArr[1].Trim();
                        tbAddr.Text = tmpArr[2].Trim();
                        tbSub.Text = tmpArr[3].Trim();
                        tbPost.Text = tmpArr[4].Trim();
                        tbEmail.Text = tmpArr[5].Trim();
                        tbPhone.Text = tmpArr[6].Trim();
                        tbMob.Text = tmpArr[7].Trim();
                    }
                }
            }
            lbContact.SelectedIndex = lbContact.FindString(findNames);
        }
    }