C# 简单但令人沮丧的列表框和文本框再次搜索
我花了几天时间到处寻找解决办法。 这是Visual Studio 2013为C编写的,我是一名新手: 两个文本框“姓氏”和“名”,以及一个列表框,其中包含5个名称“希金斯M”、“希金斯J”、“国王J”、“特兰a”、“邓普西S”。我将列表框属性设置为已排序。 如果我在listbox中选择Higgins J,那么单词Higgins应该出现在姓氏文本框中,而J应该出现在名字文本框中。 如果我在姓氏文本框中键入Higgins,则Higgins J应为列表框中的选定项。Higgins J将在Higgins M之前被选中。如果我在名字文本框中键入M,则选定项应从Higgins J更改为Higgins M。 但是……这些问题让我决定在这里创建一个帐户: 如果我输入Hi或Hig而不是Higgins,它必须保持这种方式,它不会在文本框中变成Higgins。只更改列表框中的索引/突出显示,而不保留文本框中的条目,无论我在文本框中键入什么。我怀疑我使用的事件是我无法完成此任务的原因。Textbox\u textchanged和listbox\u selectedindexchanged。因此,无论我在一个事件中做什么,都会自动触发另一个事件。我曾试图改变这些事件,但到目前为止结果更糟。使用:if LastName_textbox.Text=也没有帮助 如何将姓和名合并为一个索引 如果这个问题出现或听起来模棱两可,我深表歉意。我想我不知道如何用词组来搜索类似于我的问题的东西,英语不是我的第一语言。非常感谢您的帮助。谢谢 以下是部分代码:C# 简单但令人沮丧的列表框和文本框再次搜索,c#,winforms,indexing,C#,Winforms,Indexing,我花了几天时间到处寻找解决办法。 这是Visual Studio 2013为C编写的,我是一名新手: 两个文本框“姓氏”和“名”,以及一个列表框,其中包含5个名称“希金斯M”、“希金斯J”、“国王J”、“特兰a”、“邓普西S”。我将列表框属性设置为已排序。 如果我在listbox中选择Higgins J,那么单词Higgins应该出现在姓氏文本框中,而J应该出现在名字文本框中。 如果我在姓氏文本框中键入Higgins,则Higgins J应为列表框中的选定项。Higgins J将在Higgins
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\u 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;
}
[个人评论]
我还将创建一个联系人结构/类来存储您的信息以及表单中的集合,这样您只需访问文件两次:
加载时,以便可以填充集合
关闭时,以便您可以保存对文件的更改
[更新]
我的最后一句话可能不相关,因为我不知道您开发应用程序的背景,这就是为什么我说这是个人观点,您不必这么做
[更新2]
每次调用lbContact\u SelectedIndexChanged事件时,如何避免访问您的文件:
创建一个结构或类来存储联系人信息firstname、lastname、Address等。。。
创建一个集合作为窗体的类成员,该集合将包含联系人(如列表)
在frmContact_Load方法中,使用文件中包含的数据填充此集合,而不是填充列表框
因此,在您的lbContact\u SelectedIndexChanged方法中,您将在集合中搜索,而不是打开文件
添加和删除操作还必须修改集合,而不是文件
请记住在应用程序关闭时将收藏保存回文件
希望有帮助。我为遇到类似问题的人找到了解决方案,答案在文本框中。聚焦:并与从Tim中选择的listbox.Sets相结合
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);
}
}
如果是winforms,您最好相应地进行标记。另外,请显示一些代码。哦,我应该使用什么标记?winforms标记。对于将来你问的问题,我问代码的原因是为了让你的问题变得更具体,更符合你所问的上下文。这个网站主要是针对特定的技术问题,与我们从头开始编写代码的文本描述相比,使用您已有的内容会更有效率。哦,感谢您提供的提示。代码要长很多,但我没有复制添加和删除按钮功能的部分。不确定。。。因为它与问题无关?是的,没错,尽可能简洁。我马上给你好好看看,我喜欢这个。无论哪种方式,OP都需要某种方式来确定此事件是通过显式单击调用的,还是通过TextChanged事件调用的,我认为这就完成了任务+1.嘿,蒂姆,我以前试过,但没用,我想是因为这两个事件互相触发了?你介意告诉我这句话的细节吗?我不明白。指令是使用合适的数组,这就是为什么我不使用列表,除非列表在数组类别中?感谢您的帮助。它们只会相互触发,因为您在lbContact\u SelectedIndexChanged方法中设置了tbLast文本框的文本。但是如果在使用tbLast_TextChanged方法修改索引时不设置它,就不会有任何问题。对不起,我真的不明白你的意思。那么我应该怎么做来停止触发器呢?我更新了我的代码,试试这个新的。我在我的电脑上测试了它,它工作正常。