Typisiertes DataSet, bei Übernahme der Bild ID wirft er etwas durcheinander

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Typisiertes DataSet, bei Übernahme der Bild ID wirft er etwas durcheinander

    Hallo zusammen,

    ich habe eine Tabelle (MySql) mit Bilder.
    Von dieser Tabelle versuche ich die ID in eine Andere Tabelle zu übernehmen.

    Mal das Bild dazu


    Nun habe ich von ErfinderDesRades erfahren, man Arbeitet nicht mit dem DGV. OK, hat er recht.
    Das würde aber so aussehen

    VB.NET-Quellcode

    1. Private Sub BilderDataGridView_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles BilderDataGridView.CellDoubleClick
    2. Dim AdressenRow As DataSet1.AdressenRow
    3. ' Finde die Adresse mit der ID 1 -> also Bernd, weil sie im DGV ausgewählt ist
    4. AdressenRow = DataSet1.Adressen.FindByAdr_ID(AdressenDataGridView.Rows(AdressenDataGridView.CurrentRow.Index).Cells(0).Value)
    5. ' übernehme die Passende ID aus der DGV Bilder
    6. ' das geht. leider über DGV
    7. AdressenRow.Adr_Bild_ID = BilderDataGridView.Rows(e.RowIndex).Cells(0).Value
    8. End Sub


    Richtig wäre über die BindindSource zu gehen. Dazu habe ich dann folgenden Bericht gefunden
    bei vbarchiv.net
    Darauf hin habe ich meinen Code modifiziert.

    VB.NET-Quellcode

    1. Private Sub BilderDataGridView_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles BilderDataGridView.CellDoubleClick
    2. Dim AdressenRow As DataSet1.AdressenRow
    3. ' Finde die Adresse mit der ID 1 -> also Bernd, weil sie im DGV ausgewählt ist
    4. AdressenRow = DataSet1.Adressen.FindByAdr_ID(AdressenDataGridView.Rows(AdressenDataGridView.CurrentRow.Index).Cells(0).Value)
    5. ' übernehme die Passende ID aus der DGV Bilder
    6. ' Das geht mal und mal nicht. Er wirft hier vermutlich den Index durcheinander.
    7. ' http://www.vbarchiv.net/forum/read.php?id=22&t=72031&i=72031&v=f
    8. Dim DR As DataRow
    9. DR = CType(BilderBindingSource.Current, DataRowView).Row
    10. ' jetzt übergeben
    11. AdressenRow.Adr_Bild_ID = DR(0) '.ToString()
    12. ' Verzweiflungs Versuche
    13. ' Label1.Text = DR(0).ToString
    14. ' Label1.Text = DR.RowState
    15. Me.AdressenDataGridView.Update()
    16. Me.Validate()
    17. Me.BildPictureBox.Update()
    18. End Sub


    Nun geschied kurioses.
    Mal macht er es mal nicht.
    Das AdressenDataGriodView wird nicht immer Aktualiesiert. Logischerweise das Bild auch nicht.
    Jedoch die MySql DatanBank und das Label1 werden Aktualisiert.

    Weis da jemand einen Rat ?

    lieben dank
    Bernd
    ich gehe immer über die BindingSource, nämlich BindingSource.Current. Da muß man leider zweimal casten, aber daran kann man sich gewöhnen, und man kanns sogar in eine Extension-Methode für BindingSources wegkapseln.

    VB.NET-Quellcode

    1. Dim rwBild=DirectCast(DirectCast(BilderBindingSource.Current, DataRowView).Row,BildRow)
    2. Dim rwAddress=DirectCast(DirectCast(AddressBindingSource.Current, DataRowView).Row,AddressRow)
    3. rwAddress.BildRow=rwBild

    rwAddress.BildRow=rwBild - So geht das, wenn 1:n - Relation, BildTabelle->Addresse vorliegt

    Der Grund für die umständliche Casterei ist, weil BindingSource auch annere Datenquellen als Dataset unterstützt. Und weil BindingSource Filterung und zeugs weiterreicht. Der Job (Filterung und Zeugs) wird nicht von der DataTable ausgeführt, sondern von einem DataView, und da sind halt DataRowViews drin, untypisiert.
    Also sind In einer BindingSource DataRowViews drin, jedes verweist auf eine DataRow, und die Row kann man auf die typisierte Row casten.
    Also zunächst BindingSource.Current auf DataRowView casten, dann davon die Row holen, und auf typisierte Row casten.
    Naja, Code steht ja oben.

    Mit meine BindingSource-Extensions verkürzt sich der Code auf folgendes:

    VB.NET-Quellcode

    1. Dim rwBild=BilderBindingSource.At()(Of BildRow)
    2. Dim rwAddress=AddressBindingSourceAt()(Of AddressRow)
    3. rwAddress.BildRow=rwBild


    die Extensions:

    VB.NET-Quellcode

    1. ''' <summary>
    2. ''' returnt die typisierte Datarow am index. Bei ungültigem index Nothing (keine OutOfRange-Exception!)
    3. ''' </summary>
    4. <Extension()> _
    5. Public Function At(Of T As DataRow)(ByVal subj As BindingSource, ByVal index As Integer) As T
    6. Return DirectCast(subj.At(index), T)
    7. End Function
    8. ''' <summary> returnt die typisierte Datarow an aktueller Position - oder Nothing. </summary>
    9. <Extension()> _
    10. Public Function At(Of T As DataRow)(ByVal subj As BindingSource) As T
    11. Return DirectCast(subj.At(subj.Position), T)
    12. End Function
    13. ''' <summary>
    14. ''' returnt die Datarow am index. Bei ungültigem index Nothing (keine OutOfRange-Exception!)
    15. ''' </summary>
    16. <Extension()> _
    17. Public Function At(ByVal subj As BindingSource, ByVal index As Integer) As DataRow
    18. If index < 0 OrElse index >= subj.Count Then Return Nothing
    19. Return DirectCast(subj(index), DataRowView).Row
    20. End Function

    Wird bei At() der Index nicht angegeben, so wird BindingSource.Current returnt. Ansonsten halt die typisierte Datarow am angegebenen Index - braucht man auch manchmal.

    ErfinderDesRades schrieb:

    Dim rwBild=DirectCast(DirectCast(BilderBindingSource.Current, DataRowView).Row,BildRow)
    Dim rwAddress=DirectCast(DirectCast(AddressBindingSource.Current, DataRowView).Row,AddressRow)
    rwAddress.BildRow=rwBild

    ich versuche gerade zu folgen.(ausprobieren)

    geht leider nicht. Der innere DirectCast geht.
    der äußere ?? Object As Type

    wie bei dir Vorgegeben AdressRow gibt es nicht ?

    ich verstehe das leider nicht.
    also in einer an ein Dataset gebundenen BindingSource sind DataRowViews drin. daher der innere Cast

    VB.NET-Quellcode

    1. dim rw=directCast(AddressBindingSource.Current, DataRowView)
    das funzt.
    Natürlich nur, wenn du auch eine AddressBindingSource auffm Form hast, den genauen Namen deiner Objekte kann ich ja nur erahnen.

    Bernd schrieb:

    wie bei dir Vorgegeben AdressRow gibt es nicht ?
    Dasselbe. Ich hab halt AddressRow geschrieben, aber in deinem Code aus Post#1 steht was von DataSet1.AddressenRow.

    Und wie deine BilderBindingSource richtig heißt, und welchen Typ die BilderDataRows richtig haben weißichnatürlich auch nicht.

    VB.NET-Quellcode

    1. Private Sub BilderDataGridView_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles BilderDataGridView.CellDoubleClick
    2. ' Erfinder des Rades
    3. Dim rwBild = DirectCast(DirectCast(BilderBindingSource.Current, DataRowView).Row, BildRow)
    4. Dim rwAddress = DirectCast(DirectCast(AdressenBindingSource.Current, DataRowView).Row, AddressenRow)
    5. rwAddress.BildRow = rwBild
    6. AdressenBindingNavigatorSaveItem_Click(Nothing, Nothing)
    7. End Sub


    So hab ich das eingebaut. Ich habe nachgeschaut an welcher BindignSource die DGV hängen.
    So müsste das aber stimmen.

    und die äußeren beiden werden mit nem roten Punkt angemeckert.
    die würden generiert, wenn du dir ein typisiertes Dataset erstelltest.

    hast du kein typisiertes Dataset?
    aber du hast doch (post#1) einen Datentyp Dataset1.AddressenRow.

    Also gibts auch eine typisierte DataTable Dataset1.AddressenDataTable.

    und eine entsprechende Bild-DataTable gibts nicht?
    BilderDataTable finde ich nirgens.
    Es gibt
    BilderBindingSource
    BilderTableAdapter

    Wann wird dieser denn erstellt ? oder muss mann den dann selber machen ?


    Hab ich aber bei den Adressen auch nicht gemacht. Macht der das im Designer ?


    ich suche mal weiter, mache noch einige versuche. irgendwann muss ich das ja mal verstehen.
    was ist den als Datamember von BilderBindingSource angegeben?

    also ich kann mir nichts anneres vorstellen, als dasses bei dir ein Dataset1 gibt, mit den Tabellen Addressen as AddressenDataTable, und Addressen enthält logisch AddressenRows.

    Und weiters gibts eine Tabelle Bilder as BilderDataTable, und Bilder enthält logisch BilderRows.

    Der DataMember der BilderbindingSource sagt den Namen der Dataset-Property, wo die Bilder drin sind. Das muß doch zu finden sein.

    oder Kannst du einen Screenshot vom Dataset-Designer uppen?
    So ich bin es Satt,

    ich mache mal ein komplett neues Projekt und erstelle alles neu.
    Ich denke mir durch die ganzen versuche wird etwas durcheinander gekommen sein.

    ich stricke das mal und melde mich, kann ja nicht sein das es nicht gehen soll.

    dauert allerdings ein wenig.
    ich stelle den Thread mal nicht auf erledigt.


    @ErfinderDesRades

    wie immer lieben dank
    wenn du mal in der Nähe bist, geb ich einen aus.

    So mal alle vier Bilder
    Der Code


    DataSet

    Form

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Bernd“ ()

    Ja, gut, nach dem Dataset hast du einfach keine BilderDataTable.

    Keine Ahnung, warum es dann in der AddressenDataTable eine Spalte "Adr_Bild_ID" gibt - ich bin selbstverständlich davon ausgegangen, das sei ein Fremdschlüssel auf eine entsprechende BilderDataTable.

    Also wozu gibts diese Spalte "Adr_Bild_ID"?
    Ich möchte im oberen Bild, ganz viele Tabellen haben.
    PLZ, Banken, Bilder, Anrede, Titel, ......usw.

    In der unteren Tabelle sind dann die Adress Daten.
    Aber die meisten Felder halt nur ID's.

    DoppelClicke ich eine Feld in der Oberen Tabelle, soll die ID einfach in die Untere Tabelle übernommen werden.


    Das versuche ich seit einigen Tagen.
    Ob ich da nun eine Relation behandeln muss oder nicht, weis ich doch garnicht.

    Ich versuche ja überhaupt erstmal die zusammenhänge zu verstehen.
    Und vielleicht das mit dem DoppelClick hin zu bekommen.


    Edit:
    In der Unteren Tabelle brauchen nur die ID's zu erscheinen. Nichmal die fertigen Daten,
    also in Klarschrift.
    Bernd Schlepütz 25.08.1966, Dorfstr. 22, 50217 Dorfhausen..........
    sondern
    1, 55, 5, 8 , 5 .....

    Bernd schrieb:

    Ich möchte im oberen Bild, ganz viele Tabellen haben.
    PLZ, Banken, Bilder, Anrede, Titel, ......usw.

    In der unteren Tabelle sind dann die Adress Daten.
    Aber die meisten Felder halt nur ID's.

    welches obere Bild? Ich sehe nur ein Bild mit Tabelle drauf, und da ist nur eine Tabelle drauf. Aber vlt. meinst du ein horizontal geteiltes Form.

    Wie willst du eine Tabelle mit Bildern bekommen, wenn in deinem Dataset keine solche DataTable angelegt ist?

    Ich kann dir jetzt was schreiben für ein BankenDataGridView, Doppelklick, und die BankenID wird übernommen. Weil Banken scheints ja zu geben.

    VB.NET-Quellcode

    1. Dim rwBank=DirectCast(DirectCast(BankenBindingSource.Current, DataRowView).Row,BankenRow)
    2. Dim rwAddress=DirectCast(DirectCast(AddressenBindingSource.Current, DataRowView).Row,AddressenRow)
    3. rwAddress.Adr_Bank_ID=rwBank.Bank_ID
    Nochmal,
    im Post "1" sind in einem Tabreiter mehrere Tabellen. Es spielt ja keine Rolle welche es ist.
    Es geht sich einzig und alleine daraum
    Mache ich auf einer "x belibigen" Tabelle, sei es den auf der Tabelle Banken oder auf der Tabelle PLZ......, einen Doppelklick
    soll die ID der Doppelgeklickten Tabelle in die Adressen Tabelle übernommen werden.

    mehr nicht.

    Ich habe im DataSet1 zweit Tabellen.
    Adressen
    Banken

    es gibt keine Relation.

    Gebe ich nun dein Beispiel ein.

    ErfinderDesRades schrieb:

    Dim rwBank=DirectCast(DirectCast(BankenBindingSource.Current, DataRowView).Row,BankenRow)
    Dim rwAddress=DirectCast(DirectCast(AddressenBindingSource.Current, DataRowView).Row,AddressenRow)
    rwAddress.Adr_Bank_ID=rwBank.Bank_ID


    wird in der letzten Überladung angemeckert.
    Der Type "BankenRow" ist nicht definiert.
    Der Type "AdressenRow" ist nicht definiert.

    Du Castest zwei mal,
    der Innere Cast geht auf ....?
    der Äußere Cast geht auf ... ?

    vielen dank

    Bernd
    mach maln zip eines lauffähigen Samples.

    Dieses aneinander vorbeigerede und gerate, was du wohl für klassen hast, geht mir auf die nerven, sry.

    Üblicherweise werden die generierten Dinger ganz schematisch generiert, und warum die bei dir nicht drinne sein sollen ist mir unverständlich.
    anbei mal mit den BindingSource-Extensions, ohne BindingNavigator-Quatsch (stattdessen ein Menü), ohne tableadapterManager und mit einem gui mit splitContainer und Docking.

    VB.NET-Quellcode

    1. Imports ErfinderDes.DataSet1
    2. Public Class Form1
    3. Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
    4. ReLoad()
    5. End Sub
    6. Private Sub ReLoad()
    7. DataSet1.Clear()
    8. Me.AdressenTableAdapter.Fill(Me.DataSet1.Adressen)
    9. Me.BankenTableAdapter.Fill(Me.DataSet1.Banken)
    10. End Sub
    11. Private Sub BankenDataGridView_CellDoubleClick( _
    12. ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) _
    13. Handles BankenDataGridView.CellDoubleClick
    14. Dim rwBank = BankenBindingSource.At(Of BankenRow)()
    15. Dim rwAddress = AdressenBindingSource.At(Of AdressenRow)()
    16. rwAddress.Adr_Bank_ID = rwBank.Bank_ID
    17. End Sub
    18. Private Sub MenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles TestToolStripMenuItem.Click, ReLoadToolStripMenuItem.Click, SaveToolStripMenuItem.Click
    19. Select Case True
    20. Case sender Is TestToolStripMenuItem
    21. Case sender Is ReLoadToolStripMenuItem
    22. ReLoad()
    23. Case sender Is SaveToolStripMenuItem
    24. Me.Validate()
    25. Me.BankenBindingSource.EndEdit()
    26. BankenTableAdapter.Update(DataSet1)
    27. AdressenTableAdapter.Update(DataSet1)
    28. System.Media.SystemSounds.Asterisk.Play()
    29. End Select
    30. End Sub
    31. End Class


    nicht lauffähig, da das Passwort aus dem ConnectionString entfernt ;)
    Dateien