Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 简单但令人沮丧的列表框和文本框再次搜索_C#_Winforms_Indexing - Fatal编程技术网

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

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

我花了几天时间到处寻找解决办法。 这是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=也没有帮助

如何将姓和名合并为一个索引

如果这个问题出现或听起来模棱两可,我深表歉意。我想我不知道如何用词组来搜索类似于我的问题的东西,英语不是我的第一语言。非常感谢您的帮助。谢谢

以下是部分代码:

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方法修改索引时不设置它,就不会有任何问题。对不起,我真的不明白你的意思。那么我应该怎么做来停止触发器呢?我更新了我的代码,试试这个新的。我在我的电脑上测试了它,它工作正常。