Autor Beitrag
ralph71
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 54



BeitragVerfasst: Do 03.11.16 15:46 
Hallo zusammen,
habe zu meinem Grundproblem leider nichts gefunden bzw. auch Lösungen nicht verstanden, daher hier meine Frage:
Ich habe in VS 2015 im form1 ein Grid mit Datenbankanbindug erstellt.
Über Doppelklick auf einen Zeile im form1 möchte ich das form2 mit genau diesem Datensatz öffnen um dort weitere Daten einsehen bzw. ändern zu können.
Beispiel:
form1: Liste mit Angestellten
form2: Detailinfos zu dem in form1 ausgewählten Angestellten.

Hab zwar hinbekommen, das form2 zu öffnen, aber natürlich zeigt er mir immer den ersten Datensatz an...
Wie ist das zu realisieren? bin absoluter C#-Einsteiger (leider)

Danke
Grüße
Ralph
Csharp-programmierer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Do 03.11.16 16:19 
Hallo,
für dein Problem ist der Konstruktor einer Klasse da. Du definiert einen String oder einen anderen Datentyp in dem Konstruktor. Dann definierst du eine klasseninterne Variable und setzt diese mit der des Konstruktors gleich.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
public Form2(string Form1Data)
{
    InitializeComponent();
    MeineLiebeVariable = Form1Data;
}


So übergibst du der Form dann schon mal die Daten. Wenn du nun die Form instanzierst, musst du natürlich den passenden Wert mitgeben:
ausblenden C#-Quelltext
1:
Form2 form = new Form2("HierkommendieDatenrein");					

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein


Zuletzt bearbeitet von Csharp-programmierer am Do 03.11.16 16:23, insgesamt 1-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 03.11.16 16:22 
Ob das natürlich ist ist kaum zu beurteilen denn wir wissen nicht wie du das gemacht hast. Es gibt eine Unzahl von Wegen die man beschreiten kann um das zu tun was du tun willst.
Wenn du nur einen Datensatz anzeigen willst dann übergib auch nur diesen Datensatz an die 2.te Form. Bzw. übergebe etwas das diesen Datensatz eindeutig identifiziert wenn sich die 2.te Form die entsprechenden Daten selber wieder von irgendwoher herholen soll und nicht vom Aufrufer übergeben bekommt.

Egal wie du es letztendlich gelöst hast oder lösen willst. Gemeinsam ist allen das du Form1 an Form2 etwas übergeben mußt. Entweder den Datensatz oder ein Identifikator des Datensates.
Deine zweite Form braucht also eine Property/Methode/Konstruktor/überschriebene Methode oder sowas dem du die entsprechenden Daten mitgibst.
ralph71 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 54



BeitragVerfasst: Do 03.11.16 16:50 
Hallo,
danke für die schnelle Antwort.

Übergabe der Daten: so wie ich das sehe, dürfte es deutlich schneller sein, wenn das form2 den vollständigen Datensatz aus der Datenbank beim öffnen liest, oder?
Eindeutig ist der Datensatz definitiv. Das Feld ID ist Primärschlüssel.
Das hier irgendwie eine Übergabe der per Doppelklick gewählten ID nötig ist, war mir klar. Auch logisch ist, dass das form2 nur den einen Satz mit Schlüssel ID von der DB holt.
Die genannten Codezeilen verstehe ich schon, aber klick hats jetzt noch nicht gemacht...
Sorry, aber irgendwie bitte ich jetzt darum, dass mir das vorgebetet wird und ich das dann verstehe... :-(
Csharp-programmierer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Do 03.11.16 17:03 
Zitat:
Die genannten Codezeilen verstehe ich schon, aber klick hats jetzt noch nicht gemacht...
Sorry, aber irgendwie bitte ich jetzt darum, dass mir das vorgebetet wird und ich das dann verstehe... :-(


Stell dir die Klasse wie ein Haus vor. Das Haus möchte wissen, welche Farbe es hat, wie viele Etagen, wie viele Zimmer (...). Damit die Klasse mit den Daten arbeiten kann, musst du ihr diese Daten geben. Das machst du über den Konstruktor. Der ist sozusagen das Bindeglied zwischen den anderen Formen und der einen Klasse. In dem Konstruktor entsteht sozusagen das Haus. Hier werden dann die jeweiligen Daten aus der anderen Form zugeteilt.
In diesem Beispiel denkt sich die Klasse dann, ah gut, ich bin ein blaues Haus, ich habe 3 Etagen und 5 Zimmer, vielen Dank, Form1. Aber damit diese Klasse das weiß, muss eine andere Klasse dieser Klasse das auch sagen, welche Daten mitgegeben werden. In diesem Beispiel würde der Code dann z.B. so aussehen:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
private Color hausFarbe;
private int anzahlEtagen;
private int anzahlZimmer;

public HausClass(Color Farbe, int Etagen, int Zimmer)
{
   // Damit jetzt die Methoden dieser Klasse wissen, welche Daten diese Klasse hat, müssen nun interne Variablen über den Konstruktor erstellt werden.
   // Deswegen weisen wir diesen Variablen nun ihren Wert zu:

   hausFarbe = Farbe;
   anzahlEtagen = Etagen;
   anzahlZimmer = Zimmer;
}


Das ist nötig, da die Daten, die du der Klasse übergibst, nur in dem Konstruktor sichtbar sind. Da du andere Methoden in dieser Klasse mit dem entsprechenden Daten versorgen willst, brauchst du Variablen, die in der ganzen Klasse verfügbar sind.
Jetzt weiß das Haus also, wie es aussieht ;)

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 03.11.16 17:53 
Zitat:
Sorry, aber irgendwie bitte ich jetzt darum, dass mir das vorgebetet wird und ich das dann verstehe... :-(


Zeig was du hast. Wir wissen immer noch nicht wovon du genau sprichst. Zum Beispiel ist Datensatz ein sehr weit gefasster Begriff. Wenn du von Primärschlüssel sprichst kann ich erraten das es irrgendwas ist das direkt aus einer Datenbank fällt aber das ist auch nur ein Spezialfall. Techniken um mit Datenbanken zu sprechen gibt es mehrere, wenn wir auch die exotischen,abstrusen u.s.w. dazunehmen mehrere Dutzend. Es hilft hier sichern nicht irrgendeinen Weg zu zeigen.
ralph71 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 54



BeitragVerfasst: Fr 04.11.16 08:11 
Datensatz: da hast du Recht. Ist in diesem Beispiel eine Zeile in einer Tabelle mit Primärschlüssel.
was ich habe.... Viel is es nicht. :-(

im form1 ruf das Ereignis "Doppelklick" diese Methode auf wobei die lokID der Primärschlüssel der Tabelle ist:

ausblenden C#-Quelltext
1:
2:
3:
4:
         int lokID;
            lokID = int.Parse((metroGrid1.SelectedCells[0].Value.ToString()));
            VDetails vd = new VDetails(lokID);
            vd.Show();


im form2 (=VDetails) wird die ID übernommen:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
    public partial class VDetails : MetroFramework.Forms.MetroForm
    {
        private int lvID;
        public VDetails(int Form1Data)
        {
            InitializeComponent();
            lvID = Form1Data;
        }

        private void VDetails_Load(object sender, EventArgs e)
        {
            // TODO: Diese Codezeile lädt Daten in die Tabelle "visualDataSet1.T_Veranstaltung". Sie können sie bei Bedarf verschieben oder entfernen.
            this.t_VeranstaltungTableAdapter.Fill(this.visualDataSet1.T_Veranstaltung);
            
        }
    }


Aktueller Stand: das form2 hat beim Öffnen die ID im Bauch. D.h. jetzt muss diese Zeile ("this.t_VeranstaltungTableAdapter.Fill(this.visualDataSet1.T_Veranstaltung);"), die ja alle Datensätze planlos abholt durch eine ersetzt werden, die nur den Satz mit der übergebenen ID abholt....

Moderiert von user profile iconChristian S.: C#-Tags hinzugefügt
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 04.11.16 12:52 
Ok du scheinst mit einem typisierten Dataset zu arbeiten.

Möglichkeiten:

a.) Du ergänzt den t_VeranstaltungTableAdapter um eine Methode ähnlich Fill die nur den einen Datensatz aus der Datenbank holt.
Wie man solch eine Methode über den Dataset Designer anlegt wäre hier beschrieben.
b.) Wenn du den Tableadapter ganz normal erzeugt hast hat der schon ein entsprechende Methode. Die heißt üblicherweise FindByDERNAMEMEINESLIEBENPRIMARYKEY und gibt dir das passende DataRow Object zurück.
C.) Du übergibst nicht nur die ID sondern auch die DataTable/DataSet damit die Form damit arbeiten kann und holst die Daten nicht nochmal aus der Datenbank. Du hast sie ja eigentlich schon.
An der DataTable gibt es eine Select Methode den man einen Filter mitgeben kann. etwa visualDataSet1.T_Veranstaltung.Select($"meineLiebeID = {Form1Data}")
d.) du übergibst gleich das DataRow Object von Form1 an Form2 anstatt die Id.
ralph71 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 54



BeitragVerfasst: Fr 04.11.16 13:24 
da kommt wohl nur a) in Frage.
Das Grid soll künftig als Quelle einen View mit wenig Spalten als Datenquelle haben. Erst durch klick auf den entsprechenden Eintrag werden die restlichen "1000" Felder geladen.
Ich versuch das mal zu bauen....
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 04.11.16 14:48 
Ne das klingt falsch.

Ein Tableadapter ist so gedacht das aus allen Methoden die Daten abrufen da immer das gleiche DataRow Object rauskommt. Verschiedene Fill/FindBy Methoden sollten also nur Filtern heißt andere Zeilen zurückliefern aber immer die gleichen Spalten. In deinem Fall wäre ein andere Tableadapter dann eher die Wahl.
ralph71 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 54



BeitragVerfasst: Do 10.11.16 08:25 
In deinem Fall wäre ein andere Tableadapter dann eher die Wahl.
--> das sehe ich auch so. Der zweite Adapter muss lediglich als WHERE-Bedingung die ID aus der Auswahl des ersten Adapters haben.
Wie kann ich diese WHERE-Bedingung mit einer Variablen belegen? Ich würde dann im LOAD-Ereignis den Adapter mit der übergebenen "WHERE-Variablen" aufrufen.
Anmerkung: ich habe jahrelang Access programmiert, kann mir also die Konstrukte und Lösungsansätze sehr gut vorstellen. Es mangelt aber an den C#-Kenntnissen. :-(
Aber irgendwo muss man mal anfangen....

Moderiert von user profile iconChristian S.: Beiträge zusammengefasst

so, einen Schritt weiter:
habe im TableAdapter-Abfrage erstellt, die fehlerfrei funktioniert
ausblenden SQL-Anweisung
1:
.....WHERE IDTeilnehmer = @IDTeilnehmer					

Jetzt fehlt nur noch die Belegung der @IDTeilnehmer über die in From1 ausgewählten ID....

Moderiert von user profile iconTh69: SQL-Tags hinzugefügt
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 10.11.16 10:57 
Wenn du das per Dataset Designer gemacht hast dann hast du jetzt eine FillByIDTeilnehmer Methode am Tableadpater die du einfach aufrufst und die passende ID übergibst. Oder war der letzte Satz eher eine Handlungsanweisung an dich selbst und keine Frage?
ralph71 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 54



BeitragVerfasst: Do 10.11.16 11:17 
Eher Frage. :-)
Ich habs geschafft und wohl so gemacht wie du geschrieben hast:

1. ID das gewählten Datensatzes übergeben
2. Im Load-Ereignis des Forms:
Aufruf der vorher über den Assi erstellen TableAdapter-Query "FillTeilnehmer_Full" mit übergebener ID.
ausblenden C#-Quelltext
1:
this.t_TeilnehmerTableAdapter.FillTeilnehmer_Full(this.vuTDataSet_Teilnehmer_Full.T_Teilnehmer, lokID);					


Hört sich einfach an, war aber ein langer Weg...
Ich gehe jetzt mal davon aus, dass das von der Last auf die Datenbank und Internetleitung der beste Weg ist.

Danke Dir!

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 10.11.16 12:02 
Zitat:
Ich gehe jetzt mal davon aus, dass das von der Last auf die Datenbank und Internetleitung der beste Weg ist.


Wenn am anderen Ende nicht Access oder eine andere Desktopdatenbank liegt ja.