none
Datenbinding an Textbox RRS feed

  • Frage

  • Hallo an alle,

     

    mein Name ist Carsten und ich beschäftige mich erst seit kurzem mit C#. Bisher habe ich meine Programmiererfahrungen mit VBA und VO gesammelt.

    Nun zu meiner Frage:

     

    Ich möchte über ein Formular auf eine DBF-Datenbank über den Advantage.Data.Provider zugreifen und danach über DataBinding die einzelnen Daten an Textfelder binden, über welche ich die Anzeige bzw. Änderung der Daten regeln möchte.

     

    Ich habe also ein Formular (Form2) mit einer TextBox (txtNum) gebaut. Über den folgenden Programmcode soll beim Laden der Form die Textbox gefüllt werden:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using Advantage.Data.Provider;
    
    namespace Datenbank
    {
      public partial class Form2 : Form
      {
        public Form2()
        {
          InitializeComponent();
        }
    
        private void Form2_Load(object sender, EventArgs e)
        {
          // Connection String
          string connString = "data source=T:\\VCS\\Projekte\\MinDat\\Daten\\; ServerType=remote|local; TableType=CDX; CharType=OEM";
    
          // Abfragestring
          string strSQL = "select MINNR, MINNAME, MINFBEZ, MINFORM, MINFUNDS, MINFUNDO, MINLAND from MINERAL where MINNR='I-C1A' order by MINNR";
    
          // DataAdapter zur Ausführung der Abfrage
          AdsDataAdapter dAdapter = new AdsDataAdapter(strSQL, connString);
    
          //Erzeugen DataSet mit den Daten aus der Abfrage
          DataSet dsMineral = new DataSet();
    
          //Füllen des DataSet
          dAdapter.Fill(dsMineral);
    
          //Erzeugen der BindingSource
          BindingSource bsMineral = new BindingSource();
          bsMineral.DataSource = dsMineral;
    
          //Binden an TextBox
          txtNum.DataBindings.Add(new Binding("Text", bsMineral.DataSource, "MINNAME", true));      
        }
      }
    }

    Beim Ausführen erscheint folgender Fehler:

     

    ArgumentException wurde nicht behandelt.

    An die Eigenschaft oder Spalte MINNAME für die DataSource kann nicht gebunden werden.
    Parametername: dataMember

     

    Jetzt habe ich keine Ahnung, wo mein Fehler liegt...

     

    Danke für die Hilfe

     

    Carsten

     

    Freitag, 13. August 2010 11:51

Antworten

  • Hallo Carsten,

    Den Sybase-ConnectionString habe ich jetzt mal nicht überprüft, und gehe mal davon aus, dass die Verbindung funktioniert.
    Zunächst müssen die Namen im DataTable "MINERAL" im DataSet 'dsMineral' in Deiner Select-Abfrage natürlich korrspondieren - das ist evtl. schon so.

    Im Beispiel bindest Du nur gegen das DataSet: "dsMineral". Wahrscheinlich muss es so heissen:

         txtNum.DataBindings.Add(new Binding("Text",
                bsMineral.DataSource, "
    MINERAL.MINNAME", true));
         (dazu hättest Du dann   dAdapter.Fill(dsMineral, "MINERAL");     machen müssen.

    Ansonsten, wenn bei Fill kein Name angegeben wird, dann:

         txtNum.DataBindings.Add(new Binding("Text",
         bsMineral.DataSource, "
    TABLE.MINNAME", true));

    Eine weitere Möglichkeit bestünde in den Zuweisungen:

       bsMineral.DataSource = dsMineral.Tables[0]; 
      txtNum.DataBindings.Add(new Binding("Text", bsMineral.DataSource, "MINNAME"true));

    ... der Bindungs-Mechanismusweiss weiß in Deiner Implementation ja gar nicht, aus welcher Tabelle der Name "MINNAME" gebunden werden soll.
    (Ein DataSet besteht aus mehreren DataTable's).
    Tip1: nutze ggf. besser den AdsConnectionStringBuilder zur Erstellung des ConnectionStrings.
    Tip2: nutze ggf. ein typsicheres DataSet. 
    Tip3: Update-Szenario könnte ggf. ein [AdsCommandBuilder] sinnvoll sein.
    Tip4: weitere [Fehlermöglichkeiten]. 


    ciao Frank
    Samstag, 14. August 2010 07:51
  • Hallo Carsten,

    Dein UpdateCommand sieht sehr merkwürdig aus ;-)
    Du kannst .NET hier alles selber machen lassen mit meinem "Tip 3", dem AdsCommandBuilder.
    Also füge einmal am Ende der Methode "Form2_Load" folgendes ein:

      AdsCommandBuilder builder = new AdsCommandBuilder(dAdapter);
      // MessageBox.Show(builder.GetUpdateCommand().CommandText);
    

    (ich habe mir die speziellen Ads**** Möglichkeiten zwar noch nicht angesehen und tippe jetzt darauf, aus der Kenntnis der allgemeinen Struktur bei ADO.NET-Methoden.

    Die zweite Zeile oben ist nicht notwendig und nur informatorisch für Dich, damit Du siehst, wie das UpdateCommand hätte richtig aussehen müssen (etwas anders).
    Anstatt nun Deine ganzen Zeilen im Validate-Vergleich, kannst Du dann einfach Dein EndEdit aufrufen und dann ein:

      dAdapter.Update(dsMineral);
    

    aufrufen (und kein AcceptChanges, das wird schon von Update ausgeführt).
    Das alles zwar ungeprüft bzgl. Deines Codes, aber in die Richtung solltest Du implementieren.

     


    ciao Frank
    Dienstag, 17. August 2010 16:40

Alle Antworten

  • Hallo Carsten,

    Den Sybase-ConnectionString habe ich jetzt mal nicht überprüft, und gehe mal davon aus, dass die Verbindung funktioniert.
    Zunächst müssen die Namen im DataTable "MINERAL" im DataSet 'dsMineral' in Deiner Select-Abfrage natürlich korrspondieren - das ist evtl. schon so.

    Im Beispiel bindest Du nur gegen das DataSet: "dsMineral". Wahrscheinlich muss es so heissen:

         txtNum.DataBindings.Add(new Binding("Text",
                bsMineral.DataSource, "
    MINERAL.MINNAME", true));
         (dazu hättest Du dann   dAdapter.Fill(dsMineral, "MINERAL");     machen müssen.

    Ansonsten, wenn bei Fill kein Name angegeben wird, dann:

         txtNum.DataBindings.Add(new Binding("Text",
         bsMineral.DataSource, "
    TABLE.MINNAME", true));

    Eine weitere Möglichkeit bestünde in den Zuweisungen:

       bsMineral.DataSource = dsMineral.Tables[0]; 
      txtNum.DataBindings.Add(new Binding("Text", bsMineral.DataSource, "MINNAME"true));

    ... der Bindungs-Mechanismusweiss weiß in Deiner Implementation ja gar nicht, aus welcher Tabelle der Name "MINNAME" gebunden werden soll.
    (Ein DataSet besteht aus mehreren DataTable's).
    Tip1: nutze ggf. besser den AdsConnectionStringBuilder zur Erstellung des ConnectionStrings.
    Tip2: nutze ggf. ein typsicheres DataSet. 
    Tip3: Update-Szenario könnte ggf. ein [AdsCommandBuilder] sinnvoll sein.
    Tip4: weitere [Fehlermöglichkeiten]. 


    ciao Frank
    Samstag, 14. August 2010 07:51
  • Hallo Frank,

     

    danke für Deine Hilfe. Es funktioniert mit den kleinen Änderungen im Programmcode.

     

    Deine zusätzlichen Tipps werde ich auch mal anschauen und ggf. einbauen.

     

    Carsten

    Montag, 16. August 2010 09:56
  • Da bin ich wieder und versuche die  in der Textbox geänderten Daten in die Datei zurückzuspeichern.

     

    Daten werden aus der Datei geholt und in den Textboxen der Form angezeigt:

     

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using Advantage.Data.Provider;
    
    namespace Datenbank
    {
      public partial class Form2 : Form
      {
        public Form2()
        {
          InitializeComponent();
        }
    
        string connString;
        string strSQL;
        string strUPD;
        DataSet dsMineral;
        AdsDataAdapter dAdapter;
        BindingSource bsMineral;
        AdsConnection conn;
    
    
        private void Form2_Load(object sender, EventArgs e)
        {
          // Connection String
          this.connString = "data source=T:\\VCS\\Projekte\\MinDat\\Daten\\; ServerType=remote|local; TableType=CDX; CharType=OEM";
    
    
          // Abfragestring
          this.strSQL = "select MINNR, MINNAME, MINFBEZ, MINFORM, MINFUNDS, MINFUNDO, MINLAND from MINERAL where MINNR = 'II-A1A' order by MINNR";
    
          // Updatestring
          this.strUPD = "update MINERAL set MINFBEZ ='" + txtFBez +"'";
    
          // DataAdapter zur Ausführung der Abfrage
          this.dAdapter = new AdsDataAdapter(strSQL, connString);
    
          //Erzeugen DataSet mit den Daten aus der Abfrage
          this.dsMineral = new DataSet();
    
          //Füllen des DataSet
          dAdapter.Fill(dsMineral, "L");
    
          //Erzeugen der BindingSource
          this.bsMineral = new BindingSource();
          bsMineral.DataSource = dsMineral;
    
          //Binden an TextBox
          txtNum.DataBindings.Add(new Binding("Text", bsMineral.DataSource, "L.MINNR", true));
          txtName.DataBindings.Add(new Binding("Text", bsMineral.DataSource, "L.MINNAME", true));
          txtFBez.DataBindings.Add(new Binding("Text", bsMineral.DataSource, "L.MINFBEZ", true));
          txtForm.DataBindings.Add(new Binding("Text", bsMineral.DataSource, "L.MINFORM", true)); 
        }
    

     

    Im Formular werden die Daten geändert und sollen über einen Klickbutton in die Datendatei zurückgesichert werden.

        private void button2_Click(object sender, EventArgs e)
        {
          if (this.Validate())
          {
            AdsConnection conn = new AdsConnection("data source=T:\\VCS\\Projekte\\MinDat\\Daten\\; ServerType=remote|local; TableType=CDX; CharType=OEM");      
            conn.Open();
    
            this.dAdapter.UpdateCommand = conn.CreateCommand();
            this.dAdapter.UpdateCommand.CommandText = "update MINERAL set MINFBEZ ='" + txtFBez + "'";
            
            this.bsMineral.EndEdit();
            this.dAdapter.Update(dsMineral, "L");
            this.dsMineral.AcceptChanges();     
    
            MessageBox.Show("Fertig");
          }
          else
          {
            MessageBox.Show("Fehler");
          }
    

    Wenn ich die Sprungmarken im Debugmode auswerte kann ich nachverfolgen, dass im UpdateCommand der richtige Wert bereitsteht. Auch das Dataset ist mit den richtigen Werten gefüllt. Nur die Änderungen kommen nicht in der Datenbank an.

     

    Wieso???

     

    Danke für die Hilfe

     

    Carsten

     

     

     

     

    Dienstag, 17. August 2010 14:05
  • Hallo Carsten,

    Dein UpdateCommand sieht sehr merkwürdig aus ;-)
    Du kannst .NET hier alles selber machen lassen mit meinem "Tip 3", dem AdsCommandBuilder.
    Also füge einmal am Ende der Methode "Form2_Load" folgendes ein:

      AdsCommandBuilder builder = new AdsCommandBuilder(dAdapter);
      // MessageBox.Show(builder.GetUpdateCommand().CommandText);
    

    (ich habe mir die speziellen Ads**** Möglichkeiten zwar noch nicht angesehen und tippe jetzt darauf, aus der Kenntnis der allgemeinen Struktur bei ADO.NET-Methoden.

    Die zweite Zeile oben ist nicht notwendig und nur informatorisch für Dich, damit Du siehst, wie das UpdateCommand hätte richtig aussehen müssen (etwas anders).
    Anstatt nun Deine ganzen Zeilen im Validate-Vergleich, kannst Du dann einfach Dein EndEdit aufrufen und dann ein:

      dAdapter.Update(dsMineral);
    

    aufrufen (und kein AcceptChanges, das wird schon von Update ausgeführt).
    Das alles zwar ungeprüft bzgl. Deines Codes, aber in die Richtung solltest Du implementieren.

     


    ciao Frank
    Dienstag, 17. August 2010 16:40