2016-09-20 3 views
0

Ich bin neu in der Programmierung und in diesem Forum. Ich habe das Forum nach Antworten gesucht, aber habe nichts gefunden, was für mich funktioniert. Ich habe ein Adressbuch in WinForms mit einer Suchfunktion erstellt. Die Suche findet den angegebenen Kontakt, aber wenn ich auf den Kontakt klicke, gehört die von ihm geladene Information zum ersten Kontakt in der Liste. Dies geschieht für jeden Kontakt in der Liste außer für den ersten Kontakt.Suche nach Namen in der Liste

var TempVar = People.Where(a => a.Namn.ToLower().Contains(txtSearchbar.Text.ToLower()) || 
      a.PostOrt.ToLower().Contains(txtSearchbar.Text.ToLower())).ToList(); 

      foreach (var item in TempVar) 
      { 
       ListBoxOne.Items.Add(TempVar); 
      } 

Sagen Sie mir, wenn Sie weitere Informationen benötigen. Danke für die Hilfe !!

EDIT1:

weiß nicht, ob dies der richtige Weg ist, zu beantworten, aber der Kommentar-Abschnitt nur knapp sein Ziel lassen Sie mich eine lange Antwort posten.

Für den Anfang. Danke, dass du so hilfsbereit bist. Ich habe versucht, Ihren Code für das Hinzufügen zu der Liste, aber habe den Fehlercode: Kann System.Collecion.Generic.List zu System.Windows.Forms.ListBox.ObjectCollection nicht konvertieren. Suche im Internet nach einer Lösung, aber kam zu kurz. Soll ich meinen gesamten Code posten? Habe auch deinen Suchcode ausprobiert, es funktioniert super. Aber mein Hauptproblem ist immer noch da. Wenn ich auf die Suchergebnisse klicke, zeigt der Name in der Listbox die Kontaktinformationen des ersten Kontakts in der gesamten Kontaktliste an. Es ist, als ob der Index der Kontakte immer noch in der Listbox ist, aber wenn die Kontakte in der Listbox durch die Suchfunktion aussortiert werden, wird der erste Kontaktindex dem gefundenen Kontakt gegeben. Soll ich meinen gesamten Code posten, um alles klarer zu machen? Danke für die Hilfe!

EDIT2: Hier ist der Code. Ich habe eine Klasse mit Personeneigenschaften bekommen. Name, Adresse, Postnumber, Stadt, Telefon und E-Mail, die auf die Liste verweist.

Ich weiß, einige der Kommentare sind in schwedisch und es ist ein Aufwand. Frag mich, ob du etwas verstehst.

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 
    List<Person> People = new List<Person>();//Skapar en lista med alla variabler i Person 

    private void Form1_Load(object sender, EventArgs e)//Reads file on start up. 
    { 
     //string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); 
     if (Directory.Exists("C:\\visualFolder\\Adressbok")) 
     { 
      Directory.CreateDirectory("C:\\visualFolder\\Adressbok"); 
     } 
     if (!File.Exists("C:\\visualFolder\\Adressbok\\settings.xml")) 
     { 
      XmlTextWriter XW = new XmlTextWriter("C:\\visualFolder\\Adressbok\\settings.xml", Encoding.UTF8); 
      XW.WriteStartElement("People"); 
      XW.WriteEndElement(); 
      XW.Close(); 
     } 
     XmlDocument xDoc = new XmlDocument(); 
     xDoc.Load("C:\\visualFolder\\Adressbok\\settings.xml"); 

     foreach (XmlNode XNode in xDoc.SelectNodes("People/Person")) 
     { 
      Person p = new Person(); 
      p.Namn = XNode.SelectSingleNode("Namn").InnerText; 
      p.GatuAdress = XNode.SelectSingleNode("Adress").InnerText; 
      p.PostNummer = XNode.SelectSingleNode("Postnummer").InnerText; 
      p.PostOrt = XNode.SelectSingleNode("Postort").InnerText; 
      p.Telefon = XNode.SelectSingleNode("Telefon").InnerText; 
      p.Email = XNode.SelectSingleNode("Email").InnerText; 
      People.Add(p); 
      ListBoxOne.Items.Add(p.Namn); 


     } 

    }//---- 

    private void cmdRegistrera_Click(object sender, EventArgs e)//Adds contact 
    { 
     Person LäggTillPerson = new Person(); 
     LäggTillPerson.Namn = txtNamn.Text; 
     LäggTillPerson.GatuAdress = txtAdressText.Text; 
     LäggTillPerson.PostNummer = txtPostNummer.Text; 
     LäggTillPerson.PostOrt = txtPostOrt.Text; 
     LäggTillPerson.Telefon = txtTelefonnummer.Text; 
     LäggTillPerson.Email = txtEpost.Text; 
     People.Add(LäggTillPerson); 
     ListBoxOne.Items.Add(LäggTillPerson.Namn); 

     txtNamn.Clear(); 
     txtAdressText.Clear(); 
     txtPostNummer.Clear(); 
     txtPostOrt.Clear(); 
     txtTelefonnummer.Clear(); 
     txtEpost.Clear(); 

    } 

    private void cmdTaBort_Click(object sender, EventArgs e)//Deletes contact. 
    { 

     if (ListBoxOne.SelectedItem != null) 
     { 

      People.RemoveAt(ListBoxOne.SelectedIndex); 
      ListBoxOne.Items.Remove(ListBoxOne.SelectedItems[0]); 
     } 


     txtNamn.Clear(); 
     txtAdressText.Clear(); 
     txtPostNummer.Clear(); 
     txtPostOrt.Clear(); 
     txtTelefonnummer.Clear(); 
     txtEpost.Clear(); 

    } 


    private void ListboxOne_SelectedIndexChanged(object sender, EventArgs e)// 
    { 
     if (ListBoxOne.SelectedItem != null) 
     { 
      txtNamn.Text = People[ListBoxOne.SelectedIndex].Namn; 
      txtAdressText.Text = People[ListBoxOne.SelectedIndex].GatuAdress; 
      txtPostNummer.Text = People[ListBoxOne.SelectedIndex].PostNummer; 
      txtPostOrt.Text = People[ListBoxOne.SelectedIndex].PostOrt; 
      txtTelefonnummer.Text = People[ListBoxOne.SelectedIndex].Telefon; 
      txtEpost.Text = People[ListBoxOne.SelectedIndex].Email; 
     } 

    } 

    private void cmdSpara_Click(object sender, EventArgs e)//Saves changes. 
    { 
     if (ListBoxOne.SelectedItem != null) 
     { 
      People[ListBoxOne.SelectedIndex].Namn = txtNamn.Text; 
      People[ListBoxOne.SelectedIndex].GatuAdress = txtAdressText.Text; 
      People[ListBoxOne.SelectedIndex].PostNummer = txtPostNummer.Text; 
      People[ListBoxOne.SelectedIndex].PostOrt = txtPostOrt.Text; 
      People[ListBoxOne.SelectedIndex].Telefon = txtTelefonnummer.Text; 
      People[ListBoxOne.SelectedIndex].Email = txtEpost.Text; 

      ListBoxOne.Items.Clear(); 

      foreach (var item in People) 
      { 
       ListBoxOne.Items.Add(item.Namn); 
      } 
     } 

     MessageBox.Show("Ändringarna är sparade"); 

    } 

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)//Saves to file on when closin the application. 
    { 
     XmlDocument xDoc = new XmlDocument(); 
     xDoc.Load("C:\\visualFolder\\Adressbok\\settings.xml"); 
     XmlNode xNode = xDoc.SelectSingleNode("People"); 
     xNode.RemoveAll(); 

     foreach (Person p in People) 
     { 
      XmlNode xTop = xDoc.CreateElement("Person"); 
      XmlNode Xnamn = xDoc.CreateElement("Namn"); 
      XmlNode Xadress = xDoc.CreateElement("Adress"); 
      XmlNode XPostnummer = xDoc.CreateElement("Postnummer"); 
      XmlNode XpostOrt= xDoc.CreateElement("Postort"); 
      XmlNode Xtelefon = xDoc.CreateElement("Telefon"); 
      XmlNode XeMAil = xDoc.CreateElement("Email"); 

      Xnamn.InnerText = p.Namn; 
      Xadress.InnerText = p.GatuAdress; 
      XPostnummer.InnerText = p.PostNummer; 
      XpostOrt.InnerText = p.PostOrt; 
      Xtelefon.InnerText = p.Telefon; 
      XeMAil.InnerText = p.Email; 

      xTop.AppendChild(Xnamn); 
      xTop.AppendChild(Xadress); 
      xTop.AppendChild(XPostnummer); 
      xTop.AppendChild(XpostOrt); 
      xTop.AppendChild(Xtelefon); 
      xTop.AppendChild(XeMAil); 

      xDoc.DocumentElement.AppendChild(xTop); 

     } 
     xDoc.Save("C:\\visualFolder\\Adressbok\\settings.xml"); 


    } 

    private void cmdSök_Click(object sender, EventArgs e)//Search function. This is where the problem is. 
    { 

     if (txtSearchbar.Text != "") 
     { 

      var term = txtSearchbar.Text; 
      var results = People.Where(a => ContainsCI(a.Namn, term) 
             || ContainsCI(a.PostOrt, term)); 

      foreach (var item in results) 
      { 
       ListBoxOne.Items.Add(item); 
      } 

      ListBoxOne.Items.Clear(); 


      foreach (var item in results) 
      { 
       ListBoxOne.Items.Add(item.Namn); 
      } 
      txtSearchbar.Clear(); 


     } 

     else 
     { 
      ListBoxOne.Items.Clear(); 

      foreach (var item in People) 
      { 
       ListBoxOne.Items.Add(item.Namn); 
      } 


     } 

    } 

    private void cmdClearSearch_Click(object sender, EventArgs e)//Clears the searchebar and ListBox and loads the contacts again. 
    { 
     ListBoxOne.Items.Clear(); 
     txtSearchbar.Clear(); 

     foreach (var item in People) 
     { 
      ListBoxOne.Items.Add(item.Namn); 
     } 


     txtNamn.Clear(); 
     txtAdressText.Clear(); 
     txtPostNummer.Clear(); 
     txtPostOrt.Clear(); 
     txtTelefonnummer.Clear(); 
     txtEpost.Clear(); 

    } 

    public bool ContainsCI(string input, string term)//Search function. courtesy of Panagiotis Kanavos 
    { 
     if (String.IsNullOrWhiteSpace(input)) 
     { 
      return false; 
     } 
     //Returns true even if `terms` is empty, just like String.Contains 
     return input.IndexOf(term, StringComparison.CurrentCultureIgnoreCase) != -1; 
    } 
} 

}

+5

'ListBoxOne.Items.Add (TempVar);' Sie wollen definitiv 'ListBoxOne.Items.Add (Element);' – Jonesopolis

+0

Ich kann weder eine 'Contact'-Klasse noch ein' Adressbuch' noch irgendetwas anderes sehen auf diese Frage. – HimBromBeere

+3

Besser noch, 'AddRange (TempVar)' –

Antwort

4

Ihr Code hat einen Tippfehler. Anstatt einzelne Elemente hinzuzufügen, fügen Sie die Liste selbst zur Listbox hinzu. Sie sollten die einzelnen Elemente hinzufügen:

foreach (var item in TempVar) 
{ 
    ListBoxOne.Items.Add(item); 
} 

Eine bessere Option obwohl AddRange zu verwenden wäre, die gesamte Liste hinzuzufügen auf einmal:

ListBoxOne.Items.AddRange(TempVar); 

Sie können auch den Rest des Codes verbessern. Statt Contains, bei dem die Groß-/Kleinschreibung beachtet wird, können Sie IndexOf mit einem StringComparison-Parameter verwenden, bei dem die Groß- und Kleinschreibung nicht berücksichtigt wird. Um den Code ein bisschen sauberer zu machen, habe ich eine separate ContainsCI Methode:

public bool ContainsCI(string input, string term) 
{ 
    if (String.IsNullOrWhitespace(input)) 
    { 
     return false; 
    } 
    //Returns true even if `terms` is empty, just like String.Contains 
    return input.IndexOf(term,StringComparison.CurrentCultureIgnoreCase)!= -1); 
} 

... 

var term=txtSearchbar.Text; 
var results= People.Where(a => ContainsCI(a.Namn, term) 
          || ContainsCI(a.PostOrt,term)); 

ListBoxOne.Items.AddRange(results); 

Durch die Verwendung von IndexOf statt Contains und ToLower() der Code temporäre Strings vermeidet zu erzeugen, die für keinen Gewinn Speicher am Ende verschwenden.

Beachten Sie, dass sowohl String.Contains als auch ContainsCItrue zurückgeben, wenn der Begriff leer ist. Dies macht es einfach, alle Elemente zurückzugeben, wenn das Suchfeld leer ist.

+1

Danke, behoben –

+0

Beantwortete in meiner Hauptfrage oben. Die Kommentarbox ließ mich keine lange Antwort geben. – AllramEst

Verwandte Themen