2016-03-25 4 views
-2

Ich habe eine winform mit Listboxen, die thourgh listbox.DataSource auf das Ereignis eines anderen listbox_SelectedIndexChanged gefüllt sind. Dies sollte eine Kaskade durch die Listenfelder erzeugen; Wenn sich listbox1 (lbCat) ändert, ändert sich die Abfrage für listbox2 (lbFam), wodurch sich die Datenquelle ändert, und dies gilt auch für listbox3 (lbProd).C# Code Schleifen unerwünscht, winform, Datensatz, sql

Allerdings zeigt das Ausgabefenster, dass beim Starten der Winform, diese Kaskadierung 3 mal statt 1 passiert ... Und ich kann nicht herausfinden, warum!

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Data.SqlClient; 
using System.Text.RegularExpressions; 
using System.Windows.Forms; 
using Excel = Microsoft.Office.Interop.Excel; 
using System.Threading; 
using System.Globalization; 
using System.Drawing; 
using System.Reflection; 

namespace LookApp2016 
{ 
    public partial class Form1 : Form 
    { 

Einstellung nur eine Schnur bis später zu verwenden, um diesen Teil überspringen, wenn Sie

 // De naam van de tabel waaruit de productcodes worden gelezen 
     string sDBproducts = "productinfo_2016"; 
     string sDBFamily = "familyinfo_2016"; 
    //kolomnamen van productinfo (zodat bij aanpassing in database alle sql queries direct veranderen) 
    string sColumnNameProductcode = "productcode"; 
    string sColumnnameCatalogus = "catalogue"; 
    string sColumnNameFamily = "productfamily"; 

    string sColumnNameProductDescription; 
    string sColumnNameSizeCM; 
    string sColumnNameSizeInch; 

    //kolomnamen van familyinfo (zodat bij aanpassing in database alle sql queries direct veranderen) 
    string sColumnNameRenDContact = "rend_contact"; 
    string sColumnNameSpecsGeneral = "specs"; //wel nog taal toevoegen aan deze string!! 

    // Strings aanmaken voor de mogelijke keuzes in de listboxes zodat deze(vooraf aan user input) toegevoegd kunnen worden aan de queries waarmee de datasets gemaakt worden. 
    string queryCategorie = "'A'"; 
    string queryValuta = "EUR"; 
    string queryTaal = "nl"; 
    string sSelectedFamily = "R&R Curve"; 
    string productcode = "R&R-C-200-60"; 
    string sFamilie = null; 


    //strings aanmaken voor invoegen in excel, start met NL 
    string sStuk = "stuk"; 
    string sStuk_multi = "stuks"; 
    string sMeter = "meter"; 
    string sMeter_multi = "meter"; 
    string sM2 = "m2"; 
    string sM2_multi = "m2"; 
    string sSet = "set"; 
    string sSet_multi = "sets"; 
    string s0 = "n.v.t."; 
    string sEenheid = "eenheid"; 
    string sAantal = "Aantal"; 
    string sTotaal = "Totaal"; 
    string sSpecificaties = "Algemene informatie:"; 
    string sPrijs = "Prijs"; 

    string sEenheidBijProductcode = "stuk"; // gelezen uit productinfo, niet familyinfo 

    SizeF sAIsize; 
    float cellHeight; 

    // Een decimal aanmaken zodat de prijs in de juiste valuta weergegeven kan worden. 
    double valutaConverter; 

    string A = "A__Straatmeubilair"; 
    string B = "B__Boomproducten"; 
    string C = "C__Bruggen"; 

    string NL = "NL"; 
    string EN = "GB"; 
    string ENI = "ENint"; 
    string DE = "DE"; 
    string FR = "FR"; 
    string SP = "SP"; 

wird so das ist, wo ich meine SqlConnection

SqlConnection conn = new SqlConnection("Data Source =MILKYWAY; Initial Catalog = 'SPD'; User Id=*******; Password = *******;"); 


    public Form1() 
    { 
     InitializeComponent(); 
     Console.WriteLine(" Opstart tijd" + DateTime.Now.Ticks.ToString()); 
     conn.Open(); 
     // De categorieën aan de lbCategorie toevoegen en A selecteren 
     lbCat.Items.Add(A); 
     lbCat.Items.Add(B); 
     lbCat.Items.Add(C); 
     lbCat.SetSelected(0, true); 

     // De valuta-opties aan de lbValuta toevoegen en EUR selecteren 
     lbValuta.Items.Add("EUR  (x1)"); 
     lbValuta.Items.Add("GBP (x0.65)"); 
     lbValuta.Items.Add("USD (x1.4)"); 
     lbValuta.Items.Add("CAD (x1.5)"); 
     lbValuta.Items.Add("OIL (x1.05)"); 
     lbValuta.SetSelected(0, true); // EUR is pre-selected 

     // De taal-opties aan de lbTaal toevoegen en NL selecteren 
     lbTaal.Items.Add(NL); 
     lbTaal.Items.Add(EN); 
     lbTaal.Items.Add(ENI); 
     lbTaal.Items.Add(DE); 
     lbTaal.Items.Add(FR); 
     lbTaal.Items.Add(SP); 
     lbTaal.SetSelected(0, true); // NL is pre-selected 

    } 


    private void lbCat_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     //FAMILIE LISTBOX VULLEN ADHV GEKOZEN CATEGORIE 
     queryCategorie = lbCat.Text.Remove(1); 
     Console.WriteLine("~~~~GEKOZEN CATEGORIE: " + queryCategorie + ". Tijd: " + DateTime.Now.Ticks.ToString().Remove(0, 14)); 
     lbFamVullen(); 
    } 

    private void lbFamVullen() 
    { 
     DataSet ds = new DataSet(); 
     string sql = "SELECT DISTINCT " + sColumnNameFamily + " FROM " + sDBproducts + " WHERE " + sColumnnameCatalogus + " LIKE '" + queryCategorie + "'"; 
     Console.WriteLine("~~~~DE lbFAM wordt gevuld met de query: " + sql + ". Tijd: " + DateTime.Now.Ticks.ToString().Remove(0, 14)); 
     SqlDataAdapter da = new SqlDataAdapter(sql, conn); 
     da.Fill(ds); 

     lbFam.DataSource = ds.Tables[0].DefaultView; 
     lbFam.DisplayMember = sColumnNameFamily; 
     lbFam.ValueMember = sColumnNameFamily; 

     conn.Close(); 
     conn.Dispose(); 
    } 

    private void lbFam_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     sSelectedFamily = lbFam.Text; 
     Console.WriteLine("~~~~De lbFam index changed. De geselcteerde familie = " + sSelectedFamily + ". Tijd: " + DateTime.Now.Ticks.ToString().Remove(0,14)); 
     lbProdVullen(); 
    } 

    private void lbProdVullen() 
    { 
     DataSet ds = new DataSet(); 
     string sql = "SELECT " + sColumnNameProductcode + " FROM " + sDBproducts + " WHERE " + sColumnNameFamily + " LIKE '" + sSelectedFamily + "'"; 
     Console.WriteLine("~~~~De lbProd wordt gevuld met de query: " + sql + ". Tijd: " + DateTime.Now.Ticks.ToString().Remove(0, 14)); 
     SqlDataAdapter da = new SqlDataAdapter(sql, conn); 
     da.Fill(ds); 

     lbProd.DataSource = ds.Tables[0].DefaultView; 
     lbProd.DisplayMember = sColumnNameProductcode; 
     lbProd.ValueMember = sColumnNameProductcode; 

     conn.Close(); 
     conn.Dispose(); 

    } 

    private void lbProd_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     productcode = lbProd.Text; 
     VeldenVullen(); 
    } 

    private void VeldenVullen() 
    { 
     Console.WriteLine("~~~~Geselecteertde productcode = " + productcode + "."); 

     string sql = "SELECT * FROM " + sDBproducts + " WHERE " + sColumnNameProductcode + " LIKE '" + productcode + "'"; 

     try 
     { 
      SqlCommand cmd = new SqlCommand(sql, conn); 
      SqlDataReader dr = cmd.ExecuteReader(); 

      if (dr.HasRows) 
      { 
       while (dr.Read()) 
       { 
        tbProductcode.Text = productcode; 
        tbProdOmschrijving.Text = dr[queryTaal + sColumnNameProductDescription].ToString(); 

        // cm AND inches if language is ENI, else only cm 
        if (queryTaal == ENI) 
        { 
         tbAfm.Text = dr[sColumnNameSizeCM].ToString() + " " + dr[sColumnNameSizeInch].ToString(); 
        } 
        else 
        { 
         tbAfm.Text = dr[sColumnNameSizeCM].ToString(); 
        } 
       } 
      } 
      dr.Close(); 
      conn.Close(); 
      conn.Dispose(); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Er is een fout gemaakt tijdens het inlezen van alle productgegevens uit de database." + Environment.NewLine + Environment.NewLine + 
       "Contacteer de ICT afdeling." + Environment.NewLine + ex.Message, 
       "Ooooops! Er is iets fout gegaan...", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 


    } 
}  

}

Antwort

2

gesetzt Der Multi-Trigger wird durch das Auslösen von Ereignissen verursacht. In Ihrem Konstruktor rufen Sie InitializeComponent(); Diese Methode bindet alle Ereignislistener an dort Kontrollen (zum Beispiel die lbCat_SelectedIndexChanged). Dies bedeutet, dass der Code in dieser Methode immer dann ausgeführt wird, wenn der ausgewählte Index des Steuerelements geändert wird. Sowohl Sie ändern den Index innerhalb des Codes oder ein Benutzer, der es mit der Maus/Tastatur tut, zählt als ein gültiger Auslöser.

Ihr Konstruktor löst einige dieser Ereignisse aus, die Ihre 'Schleife' verursachen. Um dies zu beheben, sollten Sie überprüfen, ob das Ereignis entweder vom Benutzer oder von Ihrem Code ausgelöst wird. Eine günstige und einfache Möglichkeit, dies zu tun, ist, einen Bool in Ihren Code zu setzen, der auf "false" gesetzt ist, bis Sie mit dem Laden fertig sind.

so Konstruktor:

private bool mIsLoaded;  
public Form1() 
    { 
     InitializeComponent(); 
     Console.WriteLine(" Opstart tijd" + DateTime.Now.Ticks.ToString()); 
     conn.Open(); 

     //the rest of your code here... 

     lbTaal.SetSelected(0, true); // NL is pre-selected 
     mIsLoaded = true; 
    } 

und dann Ihre Veranstaltung:

private void lbCat_SelectedIndexChanged(object sender, EventArgs e) 
     { 
      if (!mIsLoaded) { 
       return; 
      } 
      //FAMILIE LISTBOX VULLEN ADHV GEKOZEN CATEGORIE 
      queryCategorie = lbCat.Text.Remove(1); 
      Console.WriteLine("~~~~GEKOZEN CATEGORIE: " + queryCategorie + ". Tijd: " + DateTime.Now.Ticks.ToString().Remove(0, 14)); 
      lbFamVullen(); 
     } 

ich dies nur für eine Ihrer Veranstaltungen taten. Aber Sie möchten die if-Anweisung in alle Ereignisse einschließen (es sei denn, Sie möchten, dass sie auch beim Initialisieren des Systems ausgelöst werden).

Einige offtopic Dinge, die ich in Ihrem Code bemerkt:

  • In Ihrem VeldenVullen() Methode haben Sie einen Versuch catch-Anweisung. Sie schließen Ihre Verbindung innerhalb des try-Blocks. Wenn Sie eine Ausnahme haben, wird die Verbindung nie geschlossen.
  • In Ihrem custructor rufen Sie die conn.open() Ich rate, es später in einer der anderen Methoden zu verwenden, wo Sie es schließen. Auf diese Weise können Sie nur eine Methode ausführen, bevor Sie feststellen, dass Ihre Verbindung geschlossen ist, wenn Sie auf die Datenbank zugreifen. Es ist besser, eine Verbindung an der gleichen Stelle zu öffnen, an der Sie sie benutzen. Und es direkt danach schließen.
  • Ich bin niederländisch selbst, damit ich Ihre Kommentare herausfinden konnte. Aber wenn man eine Frage zu SO stellt, ist es besser, sie auf Englisch zu übersetzen, damit jeder sie verstehen kann.
  • Sie links in der Frage einschließlich Benutzername und Passwort eine Verbindungszeichenfolge
+0

Dank @ Nick Otten! Gibt es eine Möglichkeit, während der Initialisierung einmal zu triggern? So würde es kaskadieren, wenn ich rate? – dreojs16

+0

@ dreojs16: Ja, die hässliche Art, dies zu tun, ist, den kaskadierenden Zustand zu verfolgen (ein extra Bool-Feld, das verfolgt, ob das Ereignis bereits während der Initialisierung ausgeführt wurde). Ein saubererer Weg wäre, den Kaskadencode aus dem Ereignis in sein eigenes void zu verschieben. Dann können sowohl das Ereignis als auch Ihr Konstruktor die 'Kaskadierungsmethode' aufrufen. –

+0

Danke, funktioniert so ein Charme, @Nick Otten! Und danke für all die anderen nützlichen Offtopic Tipps! – dreojs16