Erweiterter Umgang mit typisiertem DataSet -> Tabellennamen lesen/Namensübergabe etc.

  • VB.NET
  • .NET (FX) 4.0

Es gibt 351 Antworten in diesem Thema. Der letzte Beitrag () ist von tragl.

    tragl schrieb:

    Wäre der Aufruf denn so korrekt für eine Form?
    Ja, wäre korrekt.
    probiers bitte aus.



    tragl schrieb:

    bei deiner Variante wüsste auch auch nicht, wie ich die BS vor dem Anzeigen des DGV filtern kann.
    Wenns um den "Verbirg-alles"-Filter geht: Den kannste im FormDesigner setzen.



    Seh ich das richtig dass deine Styling-Klasse den 1. Eintrag der bs angreift, egal wie du gefiltert ist?
    Styling-Klasse habich garnet, und die ControlStyling-Klasse macht ühaupt nix mit BindingSources.
    Also die Frage ist unklar.
    Vlt Codesnippet, was du meinst?

    ErfinderDesRades schrieb:

    Ja, wäre korrekt.
    probiers bitte aus.

    Naja, es funzt ja. Aber gefunzt hat der Aufruf über den Datentyp ja auch :D

    ErfinderDesRades schrieb:

    Wenns um den "Verbirg-alles"-Filter geht: Den kannste im FormDesigner setzen.

    Hier will ich ja beim Öffnen der Form oder des UCL einen Filter auf die Bindingsource der Combobox setzen, damit der User nur bestimmte Einträge angezeigt bekommt und nicht alle.
    Ach, ich probier' einfach mal rum :)

    ErfinderDesRades schrieb:

    Styling-Klasse habich garnet, und die ControlStyling-Klasse macht ühaupt nix mit BindingSources.
    Also die Frage ist unklar.
    Vlt Codesnippet, was du meinst

    Das hier find' ich in deiner Variante mit den UCL nicht mehr, trotzdem wird bei Fokus der Combobox direkt ein Eintrag "vorgeschlagen"

    VB.NET-Quellcode

    1. Public Class dlgPlzListe
    2. Public Sub New()
    3. InitializeComponent()
    4. Dts.Register(Me, False)
    5. Dim col = Dts.PlzListe.TourNrColumn
    6. col.DefaultValue = Dts.Tour.First.TourNr ' ein Dataset-Hack, damit die DGV-Zufügezeile eine TourNr generiert, entsprechend der FK-Constraint
    7. End Sub


    Ich bau' dann mal wieder um auf meine Form-Methode, diesmal mit Objektaufruf - deine Variante hab ich ja in der Zip und die verbleibt für
    den Fall der Fälle griffbereit ;)

    Zum Datenmodell hab ich mir mal den langen Thread mit "Menorca" durchgelesen und musste tatsächlich stellenweise schmunzeln aber
    auch hier steh hier vermutlich vor einigen Sachen, die mir absolut nicht in den Kopf wollen :/ ABER:

    Funktion -> Mitarbeiter: eine Funktion wird von vielen Mitarbeitern verwendet (1:n)
    Mitarbeiter -> User: müsste dann eine 1:1 beziehung sein - nicht jeder Mitarbeiter wird als User angelegt - aber jeder Mitarbeiter muss für Datenabfrage etc. vorhanden sein
    Standort -> Mitarbeiter: ein Standort wird von vielen Mitarbeitern verwendet (1:n)
    Standort -> Tour: ein Standort wird von vielen Touren verwendet (1:n)
    Standort -> Fahrzeug: ein Standort wird von vielen Fahrzeugen verwendet (1:n)
    Tour -> PlzListe: eine Tour wird von vielen Postleitzahlen verwendet (1:n)
    Tour -> Datenabfrage(HC & Reha): eine Tour wird in vielen Datenabfragen verwendet (1:n)
    Fahrzeug -> Datenabfrage(HC & Reha): ein Fahrzeug wird von vielen Datenabfragen verwendet (1:n)

    Sobald ich dann endlich alle Testdaten angelegt hab schick' ich dir ein Update - vermutlich erklärt sich dann auch die "Logik" hinter allen Tabellen
    auch wenn die Bezeichnungen fragwürdig erscheinen mögen :)
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Theoretisch ja, wollte das aber sauber lösen - wie bei den anderen Tabellen auch.
    Jeder Eintrag bekommt eine eindeutige ID, dahinter stecken dann alle Informationen.

    Ich denke, wie man es jetzt löst ist "wurscht" oder? :)
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    nö.
    Ich täte einen ForeignKey möglichst immer auf eine PrimaryKey-Spalte verweisen lassen.
    Das ist auch vonne Benamung her sehr schlüssig - eine Relation wäre dann so benannt:
    Tour.ID->PLZ.TourID
    Um davon abzuweichen müsste man schon Gründe haben.
    Tour.TourNr kann also weg
    Ist immer nix gutt, iwas hinzubauen, wo man sich dann später fragt: "wozu das gutt?"

    (Wurst gibts eiglich kaum jemals inne Programmierung. Bei mehreren Möglichkeiten ist fast immer eine bessere und eine schlechtere identifizierbar)

    Ich hab jetzt nochmal ein hübscheres Standort-StammDaten-Ucl gebastelt. Hatte ja gesagt: Mit ParentChildViews spart man sich die eine oder annere ComboColumn.
    Mit meim View sind sogar 3 Tabellen abgedeckt, also man muss nicht für jede Tabelle ein StammForm erfinden.



    Mit deine Forms sieh man zu. Für sone MDI-Geschichte ist das vlt. am einfachsten mit der Schmuddelei.
    Das Schmuddelige daran ist, dass man nicht weiss, ob so ein Form instanziert im Speicher rumfährt oder nicht.
    Wenn du von einem zum anderen Child-Form switcht, bleibt das vorherige Form im Speicher, und wenn du wieder zurück-switchst, wird es wiederbenutzt.
    Nur wenn du das Child-Form ausdrücklich schliesst, so wirds aussm Speicher abgeräumt.
    Und dann beim wieder hinswitchen wird ein neues erstellt.

    Das ist quasi das physikalisch-schmuddelige daran.
    Dann gibts noch die "geistige Schmuddelei" - wer "frmDingbums.Show()" schreibt, weiss nicht, wasser tut. Er weiss nicht, dass frmDingbums ein Datentyp ist, und irgendwann wirds eine blöde Gelegenheit geben, wo das nicht mehr funktioniert.
    (2 Fälle, wos Geschmuddel nicht funktioniert: 1) Wenn du auf ein Form aus einer anneren Assembly zugreifen willst, 2) Wenn du in Threading-Szenarien unterwegs bist)

    Meine Ucl-Lösung räumt bei jedem switchen das vorherige Usercontrol auf. Das ist besonders resourcen-sparend, wenn viele solche Views benötigt werden, und man will nicht alle gleichzeitig im Speicher haben.

    Aber wenn du einen Dialog öffnest, mit dlg.ShowDialog, dann bitte den dlg in einem Using-Block erstellen, dasser auch aufgeräumt wird, wenner schliesst.
    modale Dialoge richtig implementieren
    Dateien
    • LogistikTool09.zip

      (274,77 kB, 43 mal heruntergeladen, zuletzt: )

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

    Hi,

    ErfinderDesRades schrieb:

    Ich täte einen ForeignKey möglichst immer auf eine PrimaryKey-Spalte verweisen lassen.
    Das ist auch vonne Benamung her sehr schlüssig - eine Relation wäre dann so benannt:
    Tour.ID->PLZ.TourID

    tut es doch ^^


    ErfinderDesRades schrieb:

    Das Schmuddelige daran ist, dass man nicht weiss, ob so ein Form instanziert im Speicher rumfährt oder nicht.
    Wenn du von einem zum anderen Child-Form switcht, bleibt das vorherige Form im Speicher, und wenn du wieder zurück-switchst, wird es wiederbenutzt.
    Nur wenn du das Child-Form ausdrücklich schliesst, so wirds aussm Speicher abgeräumt.
    Und dann beim wieder hinswitchen wird ein neues erstellt.


    Das soll auch genau so ablaufen - am Ende werden es gar nicht allzuviele ChildForms.



    ErfinderDesRades schrieb:

    Aber wenn du einen Dialog öffnest, mit dlg.ShowDialog, dann bitte den dlg in einem Using-Block erstellen, dasser auch aufgeräumt wird, wenner schliesst.


    hatter gemacht


    Version09 schau' ich mir gleich an. EDIT zu Version09: soll eben genau so in den Admin-Settings nicht sein. Da will ich Tabelle für Tabelle bearbeiten können.
    Das, was du als Vorschlag eingebaut hast kommt ggf. im weiteren Programmverlauf für die User mal hinzu.

    Ansonsten hab ich die Beispieldaten soweit drin, die BindingSources sind umbenannt wie in deinem Tut
    codeproject.com/Articles/1033145/Databinding-for-Beginners

    und es hat alles funktioniert, wie es sollte. :)


    Gibt es eine Expression-Funktion á la "WENN" aus Excel? Er rechnet mir in Zeile 3:
    -8 Überstunden, obwohl der MA dort Urlaub hatte.



    Den Dialogaufruf kann man doch bestimmt in eine Shared Sub packen in etwa:

    VB.NET-Quellcode

    1. Public Shared Sub LoadDialog(Name As String, frm As Form)
    2. Using Name As New frm
    3. Dts.Register(frm, True)
    4. If frm.ShowDialog() = DialogResult.OK Then Dts.SaveDts(frm)
    5. End Using
    6. End Sub


    und dann aufrufen via:

    VB.NET-Quellcode

    1. Forms.LoadDialog(dlgTree, dlgTreeRaw)



    Noch ein Problem hab ich mit dem Dialogaufruf, wenn schon Private Sub New() in der Form vorhanden ist.
    Hab das erstmal über die Form_Load-Variante gelöst. Dort drin steht dann dein "ControlStyling.StyleControls(Me)"



    In "dlgUserRaw" ist eine Funktion hinterlegt, die die eingestellten Spaltenbreiten des DGV speichern soll - hast du ahnung davon? Lässt sich
    das anders/einfacher lösen? ggf. sogar über die My.Settings auf User-Ebene? Hatte das aus einem Forum gezogen, funzt natürlich nicht :P

    Da fehlt mir allerdings noch das Hintergrundwissen dazu - also lass ich das erstmal so wie jetzt.
    Die neue Datei hab ich dir angehangen. :thumbsup: Sind allerdings bisher nur die RawViews eingebunden.
    Dateien
    • LogistikTool.zip

      (661,38 kB, 40 mal heruntergeladen, zuletzt: )
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

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

    tragl schrieb:

    Den Dialogaufruf kann man doch bestimmt in eine Shared Sub packen in etwa:
    Jo, beide Varianten, ein Form zu öffnen:

    VB.NET-Quellcode

    1. Private Sub TV_main_NodeMouseDoubleClick(sender As Object, e As TreeNodeMouseClickEventArgs) Handles TV_main.NodeMouseDoubleClick
    2. Select Case e.Node.Name
    3. '1 Stammdaten
    4. Case "StammdatenMitarbeiter" : ShowMdiChild(frmStammdatenMitarbeiter)
    5. Case "StammdatenFahrzeuge" : ShowMdiChild(frmStammdatenFahrzeuge)
    6. Case "StammdatenTouren" : ShowMdiChild(frmStammdatenTouren)
    7. Case "StammdatenStandorte" : ShowMdiChild(frmStammdatenStandorte)
    8. '2 Logistik
    9. Case "LogistikPlzListe"
    10. Case "LogistikDatenabfrageHc"
    11. Case "LogistikDatenabfrageReha"
    12. '3 Erkrath
    13. Case "ErkrathZentralauswertung"
    14. '4 Admin
    15. '4.1 Tabellen
    16. Case "AdmDbMitarbeiter" : ShowDataModifyDialog(Of dlgMitarbeiterRaw)()
    17. Case "AdmDbFahrzeuge" : ShowDataModifyDialog(Of dlgFahrzeugeRaw)()
    18. Case "AdmDbTouren" : ShowDataModifyDialog(Of dlgTourenRaw)()
    19. Case "AdmDbStandorte" : ShowDataModifyDialog(Of dlgStandorteRaw)()
    20. Case "AdmDbPlzZuordnung" : ShowDataModifyDialog(Of dlgPlzZuordnungRaw)()
    21. Case "AdmDbDatenabfrageHc" : ShowDataModifyDialog(Of dlgDatenabfrageHcRaw)()
    22. Case "AdmDbDatenabfrageReha" : ShowDataModifyDialog(Of dlgDatenabfrageRehaRaw)()
    23. Case "AdmDbFunktion" : ShowDataModifyDialog(Of dlgFunktionRaw)()
    24. Case "AdmDbUser" : ShowDataModifyDialog(Of dlgUserRaw)()
    25. Case "AdmDbTree" : ShowDataModifyDialog(Of dlgTreeRaw)()
    26. '5 Beenden
    27. Case "AppBeenden" : Application.Exit()
    28. End Select
    29. End Sub
    30. Private Sub ShowMdiChild(frm As Form)
    31. With frm
    32. If .Visible Then
    33. .BringToFront()
    34. Else
    35. Dts.Register(.Self, False)
    36. ControlStyling.StyleControls(.Self)
    37. .MdiParent = Me
    38. .Show()
    39. End If
    40. End With
    41. End Sub
    42. Private Sub ShowDataModifyDialog(Of T As {Form, New})()
    43. Using dlg As New T
    44. Dts.Register(dlg, False)
    45. ControlStyling.StyleControls(dlg)
    46. If dlg.ShowDialog() = DialogResult.OK Then Dts.SaveDts(dlg)
    47. End Using
    48. End Sub

    Application.Exit ist übrigens ungewöhnlich - täte ich eher von abraten, weil ich nicht weiss, ob er dann die Settings noch speichert.
    Üblicherweise beendet man ein Programm einfach, indem man das MainForm schliesst:

    VB.NET-Quellcode

    1. Me.Close
    (Meine Wenigkeit macht für sowas nichtmal einen Button hin, weil bei jedem Fenster ist ja bereits ein Schliessen-Button dran.)



    tragl schrieb:

    wenn schon Private Sub New() in der Form vorhanden ist.
    Keine Ahnung was du meinst.
    Ich finde nirgends eine Private Sub New()

    Gibt es eine Expression-Funktion á la "WENN" aus Excel? Er rechnet mir in Zeile 3:
    Glaub nicht. Weiss aber nicht genau, was "Wenn" tut.
    Sicherlich gibts viele Excel-Funktionen, die die berechneten Spalten nicht können.
    Hier nochma Tut dazu: DataExpressions: Filter und berechnete Spalten im Dataset
    Da ist auch auf die Syntax-Doku weiterverlinkt - und was da steht, das können sie, und was nicht, das nicht.
    Vielleicht ist mit IIF( ja nachzubilden, was dir vorschwebt.

    Ansonsten hab ich mir ein Stechuhr-programm gecodet, und dabei hab ich festgestellt, dass man im Dataset Zeitspannen besser als Double verarbeiten kann denn als Timespan.
    Auch wegen der Expressions - die können nur mit Zahlen rechnen, nicht mit Timespan.
    Achja, guck - machst du ja auch so - nur du verwendest Decimal für ZeitDauern!
    Jedenfalls wenn ZeitDauern im "hh:mm"-Format eingeben will, muss man trickreiche Präsentations-Logik einbauen, die die Zahlen dann wieder als Timespan präsentiert.
    gugge Stechuhr
    Dort setze ich auch sehr viel und komplizierte DataExpressions ein.

    In "dlgUserRaw" ist eine Funktion hinterlegt, die die eingestellten Spaltenbreiten des DGV speichern soll - hast du ahnung davon? Lässt sich
    das anders/einfacher lösen?
    Ich habe für solch dieses gecoded: ComplexConverter: alles in einen String und zurück
    Aber man kommt nie ganz drumrum, ein paar Zeilen zu schreiben, die definieren, was gespeichert wern soll.
    (Wobei ich bei dgv-Spaltenbreiten bislang nicht so das rasende Bedürfnis hatte, die Spaltenbreiten zu persistieren.
    Meist kriegt mein DGV AutoColumnWidth.AllCells - dann werden keine Inhalte abgeschnitten. Und wenns dann zu breit wird, sinds zuviele Spalten - kann man ja reduzieren - siehe den MitarbeiterView auf meim uclStandortStamm )

    Dieser Beitrag wurde bereits 13 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Guckma, ich hab einen Artikel zum Grusel-FormGrabsch gefunden: Warum »Form1.Show« und Co. einem irgendwann ins Bein schießen

    Aus dem MSDN-Zitat ergibt sich nun auch eine sauberere Lösung:

    VB.NET-Quellcode

    1. Case "StammdatenMitarbeiter" : ShowMdiChild(My.Forms.frmStammdatenMitarbeiter)
    2. Case "StammdatenFahrzeuge" : ShowMdiChild(My.Forms.frmStammdatenFahrzeuge)
    3. Case "StammdatenTouren" : ShowMdiChild(My.Forms.frmStammdatenTouren)
    4. Case "StammdatenStandorte" : ShowMdiChild(My.Forms.frmStammdatenStandorte)
    Mit My.Forms. ist dann codetechnisch spezifiziert, dass es sich um etwas anneres handelt als einen Datentyp.
    Moin :)

    ErfinderDesRades schrieb:

    Guckma, ich hab einen Artikel zum Grusel-FormGrabsch gefunden: Warum »Form1.Show« und Co. einem irgendwann ins Bein schießen

    Aus dem MSDN-Zitat ergibt sich nun auch eine sauberere Lösung:
    VB.NET-Quellcode

    Case "StammdatenMitarbeiter" : ShowMdiChild(My.Forms.frmStammdatenMitarbeiter)
    Case "StammdatenFahrzeuge" : ShowMdiChild(My.Forms.frmStammdatenFahrzeuge)
    Case "StammdatenTouren" : ShowMdiChild(My.Forms.frmStammdatenTouren)
    Case "StammdatenStandorte" : ShowMdiChild(My.Forms.frmStammdatenStandorte)

    Mit My.Forms. ist dann codetechnisch spezifiziert, dass es sich um etwas anneres handelt als einen Datentyp.


    Definierst du nicht mit das Sub den Namen der Form als Form? Private Sub ShowMdiChild(frm As Form)

    VB.NET-Quellcode

    1. Private Sub ShowMdiChild(frm As Form)
    2. With frm
    3. If .Visible Then
    4. .BringToFront()
    5. Else
    6. Dts.Register(.Self, False)
    7. ControlStyling.StyleControls(.Self)
    8. .MdiParent = Me
    9. .Show()
    10. End If
    11. End With
    12. End Sub


    ErfinderDesRades schrieb:

    Jo, beide Varianten, ein Form zu öffnen:

    Danke, hab' ich so umgesetzt :thumbup: bzw. ich hab's sogar in meine Helferlein gepackt, dann isses von überall griffbereit:
    Forms.vb:

    VB.NET-Quellcode

    1. Public Class Forms
    2. Public Shared Sub ShowMdiChild(frm As Form, Parent As Form)
    3. With frm
    4. If .Visible Then
    5. .BringToFront()
    6. Else
    7. Dts.Register(.Self, True)
    8. ControlStyling.StyleControls(.Self)
    9. .MdiParent = Parent
    10. .Show()
    11. End If
    12. End With
    13. End Sub
    14. Public Shared Sub ShowDataModifyDialog(Of T As {Form, New})()
    15. Using dlg As New T
    16. Dts.Register(dlg, False)
    17. ControlStyling.StyleControls(dlg)
    18. If dlg.ShowDialog() = DialogResult.OK Then Dts.SaveDts(dlg)
    19. End Using
    20. End Sub
    21. End Class

    frmMain:

    VB.NET-Quellcode

    1. Private Sub TV_main_NodeMouseDoubleClick(sender As Object, e As TreeNodeMouseClickEventArgs) Handles TV_main.NodeMouseDoubleClick
    2. Select Case e.Node.Name
    3. '1 Stammdaten
    4. Case "StammdatenMitarbeiter" : Forms.ShowMdiChild(My.Forms.frmStammdatenMitarbeiter, Me)
    5. Case "StammdatenFahrzeuge" : Forms.ShowMdiChild(My.Forms.dlgFahrzeugSuche, Me)
    6. Case "StammdatenTouren" : Forms.ShowMdiChild(My.Forms.frmStammdatenTouren, Me)
    7. Case "StammdatenStandorte" : Forms.ShowMdiChild(My.Forms.frmStammdatenStandorte, Me)
    8. '2 Logistik
    9. Case "LogistikPlzListe"
    10. Case "LogistikDatenabfrageHc"
    11. Case "LogistikDatenabfrageReha"
    12. '3 Erkrath
    13. Case "ErkrathZentralauswertung"
    14. '4 Admin
    15. '4.1 Tabellen
    16. Case "AdmDbMitarbeiter" : Forms.ShowDataModifyDialog(Of dlgMitarbeiterRaw)()
    17. Case "AdmDbFahrzeuge" : Forms.ShowDataModifyDialog(Of dlgFahrzeugeRaw)()
    18. Case "AdmDbTouren" : Forms.ShowDataModifyDialog(Of dlgTourenRaw)()
    19. Case "AdmDbStandorte" : Forms.ShowDataModifyDialog(Of dlgStandorteRaw)()
    20. Case "AdmDbPlzZuordnung" : Forms.ShowDataModifyDialog(Of dlgPlzZuordnungRaw)()
    21. Case "AdmDbDatenabfrageHc" : Forms.ShowDataModifyDialog(Of dlgDatenabfrageHcRaw)()
    22. Case "AdmDbDatenabfrageReha" : Forms.ShowDataModifyDialog(Of dlgDatenabfrageRehaRaw)()
    23. Case "AdmDbFunktion" : Forms.ShowDataModifyDialog(Of dlgFunktionRaw)()
    24. Case "AdmDbUser" : Forms.ShowDataModifyDialog(Of dlgUserRaw)()
    25. Case "AdmDbTree" : Forms.ShowDataModifyDialog(Of dlgTreeRaw)()
    26. '5 Beenden
    27. Case "AppBeenden" : Me.Close()
    28. End Select
    29. End Sub



    ErfinderDesRades schrieb:

    Application.Exit ist übrigens ungewöhnlich - täte ich eher von abraten, weil ich nicht weiss, ob er dann die Settings noch speichert.
    Üblicherweise beendet man ein Programm einfach, indem man das MainForm schliesst:

    Auch das hab' ich geändert, Buttons sollen aber bleiben :)

    ErfinderDesRades schrieb:

    Keine Ahnung was du meinst.
    Ich finde nirgends eine Private Sub New()

    Naja, wenn ich mit der vorherigen Methode

    VB.NET-Quellcode

    1. Dim dlg As New dlgTreeRaw
    2. dlg.show()

    eine Form aufgerufen habe, die bereits eine Private Sub New() besessen hat, dann ist der Aufruf fehlgeschlagen. Ich musst alles aus Private Sub New() in Form_Load reinpacken.

    ErfinderDesRades schrieb:

    Glaub nicht. Weiss aber nicht genau, was "Wenn" tut.
    Sicherlich gibts viele Excel-Funktionen, die die berechneten Spalten nicht können.
    Hier nochma Tut dazu: DataExpressions: Filter und berechnete Spalten im Dataset
    Da ist auch auf die Syntax-Doku weiterverlinkt - und was da steht, das können sie, und was nicht, das nicht.
    Vielleicht ist mit IIF( ja nachzubilden, was dir vorschwebt.

    Ich mach' mich hier mal schlau, ggf. muss ich hier über Code das Expression-Feld füllen. Die Funktion sollte sein in etwa
    "WENN Arbeitsbeginn, Arbeitsende und Pause = 0 UND Urlaub, Krank = 0 DANN 0-Sollstunden
    "WENN Arbeitsbeginn, Arbeitsende und Pause = 0 UND Urlaub ODER Krank <> 0 DANN SollStunden - Urlaub ODER Krank
    usw.

    - aber das krieg ich schon hin :)

    ErfinderDesRades schrieb:

    Ansonsten hab ich mir ein Stechuhr-programm gecodet, und dabei hab ich festgestellt, dass man im Dataset Zeitspannen besser als Double verarbeiten kann denn als Timespan.
    Auch wegen der Expressions - die können nur mit Zahlen rechnen, nicht mit Timespan.
    Achja, guck - machst du ja auch so - nur du verwendest Decimal für ZeitDauern!
    Jedenfalls wenn ZeitDauern im "hh:mm"-Format eingeben will, muss man trickreiche Präsentations-Logik einbauen, die die Zahlen dann wieder als Timespan präsentiert.
    gugge Stechuhr
    Dort setze ich auch sehr viel und komplizierte DataExpressions ein.

    Werd' ich mir anschauen

    ErfinderDesRades schrieb:

    Ich habe für solch dieses gecoded: ComplexConverter: alles in einen String und zurück
    Aber man kommt nie ganz drumrum, ein paar Zeilen zu schreiben, die definieren, was gespeichert wern soll.
    (Wobei ich bei dgv-Spaltenbreiten bislang nicht so das rasende Bedürfnis hatte, die Spaltenbreiten zu persistieren.
    Meist kriegt mein DGV AutoColumnWidth.AllCells - dann werden keine Inhalte abgeschnitten. Und wenns dann zu breit wird, sinds zuviele Spalten - kann man ja reduzieren - siehe den MitarbeiterView auf meim uclStandortStamm )

    Auch das gugg ich mir an.


    Aber nochwas zum aktuellen Thema (erweiterter Umgang mit DataSet):

    Wie bekomm ich das hin, dass ich in den gelbt markierten Bereichen nicht die gespeicherten ID-Werte, sondern den Namen angezeigt bekomme?

    Im DGV werden die ID's angezeigt (in meinem dlgMitarbeiterRaw bekomme ich die Namen als Dropdown und die sind auch erstmal sichtbar (weil's eine Combobox ist)

    In der Combobox der Detailview wird auch die ID angezeigt, das Dropdown zeigt dann die Namen. Das Dropdown konnte ich ja über die DataSource beinflussen.
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „tragl“ ()

    tragl schrieb:

    Definierst du nicht mit das Sub den Namen der Form als Form? Private Sub ShowMdiChild(frm As Form)
    Komischer Satz. Vielleicht meinst du auch Deklarieren - nicht definieren. Definieren kann alles mögliche bedeuten, Deklarieren hingegen ist ein klar definierter Begriff - s. Grundlagen: Fachbegriffe
    Ich unterscheide immer zwischen dem Namen einer Variablen und ihrem Datentyp. Einen Namen deklariere ich als Namen - in diesem Falle: frm. Der Datentyp dieser Variable ist als Form deklariert.
    Ist daran iwas unklar?
    Alle deine Forms: frmStammdatenMitarbeiter, dlgFahrzeugSuche, frmStammdatenTouren,... erben von Form - Objekte dieser Datentypen können daher an meine Sub übergeben werden.



    ich hab's sogar in meine Helferlein gepackt, dann isses von überall griffbereit:
    Naja ShowMdiChild braucht strenggenommen nicht in die Helperlein, weil das brauchst du (hoffentlich) nirgends anders als in deim MainForm.



    eine Form aufgerufen habe, die bereits eine Private Sub New() besessen hat, dann ist der Aufruf fehlgeschlagen. Ich musst alles aus Private Sub New() in Form_Load reinpacken.
    Wie gesagt - der gesamte Code enthält kein Form mit private Sub New.
    Wäre auch Unfug, ein Form mit einer Private Sub New auszustatten.
    Private, Protected, Friend, Public - das sind die Access-Modifier-Schlüsselworte - die bestimmen, wie stark gekapselt eine Methode ist.
    Private ist die stärkste Kapselung - so eine Methode ist von aussen nicht zugreifbar.
    Eine Sub New Private zu machen würde bewirken, dass von dem Datentyp überhaupt keine Objekte erstellt werden können.
    Also eine für Normal-Betrieb völlig unbrauchbare Klasse wäre das.
    Lies diese Dinge in eim guten Buch nach. Dassis Vererbungslehre, und somit das A und O von OOP.



    tragl schrieb:

    WENN Arbeitsbeginn, Arbeitsende und Pause = 0 UND Urlaub ODER Krank <> 0 DANN SollStunden - Urlaub ODER Krank
    Ja, sowas geht, und habich in meim Stechuhr-Programm auch gemacht.
    Solche Ausdrücke hinzubasteln ist aber ziemlich nervig, v.a. im Dataset-Designer - da tippste sonstwas ein, und der sagt einfach "geht nicht" und löscht es wieder - und du kannst von vorne anfangen.
    Tipp: bastel die Ausdrücke im NotePad zusammen und paste sie im DatasetDesigner dann ein.



    Wie bekomm ich das hin, dass ich in den gelbt markierten Bereichen nicht die gespeicherten ID-Werte, sondern den Namen angezeigt bekomme?
    Die Frage versteh ich wieder nicht wirklich.
    Natürlich mit einer ComboboxColumn - wäre doch nicht das erste mal, dass du sowas machst, odr?

    Vielleicht meinst du ja die Combobox. Da musste 4Vids gugge, "DetailView" - und genau aufpassen.
    ZB den Text einer Combobox darf man nicht binden.

    ErfinderDesRades schrieb:

    Komischer Satz. Vielleicht meinst du auch Deklarieren - nicht definieren. Definieren kann alles mögliche bedeuten, Deklarieren hingegen ist ein klar definierter Begriff - s. Grundlagen: Fachbegriffe
    Ich unterscheide immer zwischen dem Namen einer Variablen und ihrem Datentyp. Einen Namen deklariere ich als Namen - in diesem Falle: frm. Der Datentyp dieser Variable ist als Form deklariert.
    Ist daran iwas unklar?

    Ja, natürlich meinte ich deklarieren. Mir is das mit dem "Fachchinesisch" noch nicht so geläufig 8-) bzw. dass man sich in jedem Fall explizit ausdrücken muss / sollte, damit Andere es verstehen.
    Du nutzt aber in der Sub ShowMdiChild ja beides und zwar frm As Form. Damit sollte ja alles abgedeckt sein, zusätzlich soll
    ich aber für den Aufruf noch ShowMdiChild(My.Forms.Formname) benutzen anstelle ShowMdiChild(Formname)- ist das nicht doppelt gemoppelt? Soll nur für mein Verständnis sein.

    ErfinderDesRades schrieb:

    Naja ShowMdiChild braucht strenggenommen nicht in die Helperlein, weil das brauchst du (hoffentlich) nirgends anders als in deim MainForm.

    Da hast du wohl recht. Schieb' ich wieder zurück zur frmMain. "ShowModifyDialog" brauch' ich allerdings öfter, wird dann in den Helferleins bleiben.

    ErfinderDesRades schrieb:

    Tipp: bastel die Ausdrücke im NotePad zusammen und paste sie im DatasetDesigner dann ein.

    Das ist mir leider auch schon aufgefallen. Hab Notepad++ immer parat für sowas. :thumbsup:

    ErfinderDesRades schrieb:

    Die Frage versteh ich wieder nicht wirklich.
    Natürlich mit einer ComboboxColumn - wäre doch nicht das erste mal, dass du sowas machst, odr?

    Vielleicht meinst du ja die Combobox. Da musste 4Vids gugge, "DetailView" - und genau aufpassen.
    ZB den Text einer Combobox darf man nicht binden.


    Naja, der wird automatisch gebunden, wenn ich von der Tabelle Mitarbeiter die "Details" auf die Form ziehe.
    Hab das jetzt aber lösen können, ich wusste nicht dass da hinter dem "+" von (DataBindings) noch die Textanzeige steckt :S



    Nochwas - angenommen ich geh zu meiner urspr. gewünschten Methode zurück:
    Child-Form öffnet sich, zu sehen ist eine leere (weil bs.filter = "1=0") Detailansicht einer Tabelle.
    Mit einem Klick auf "Suchen" soll sich das Suchfenster als Dialog (ShowDataModifyDialog / könnte man auch ShowDataSearchModifyDialog schimpfen) mit der DGV und Filtermöglichkeiten öffnen. Doppelkick
    auf die selektierte Reihe soll den Datensatz in der ChildForm anzeigen, aus der der Dialog gestartet wurde. Hab ich eine Möglichkeit den gewählten Datensatz sauber zu übergeben und zwar erstmal ReadOnly, erst
    mit Klick auf einen Button soll der bearbeitbar sein. Wär das über DialogResult lösbar, dass er z.B. den bs.Current übernimmt?

    Also in etwa so:
    -> Klick auf Suche -> -> Klick auf OK soll den Datensatz in die Form übernehmen und detailliert anzeigen.

    Ich weiß, ist nicht deine Wahl der Anzeige und Suche -wäre mir aber lieber :whistling:
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    tragl schrieb:

    Du nutzt aber in der Sub ShowMdiChild ja beides und zwar frm As Form.
    Sorry - was beides benutze ich?

    tragl schrieb:

    zusätzlich soll ich aber für den Aufruf noch ShowMdiChild(My.Forms.Formname) benutzen anstelle ShowMdiChild(Formname)- ist das nicht doppelt gemoppelt? Soll nur für mein Verständnis sein.
    Zusätzlich zu was?
    Ich sags nochmal: die Formulierung ShowMdiChild(DatentypName) ist syntaktischer Quatsch, denn ein Datentyp ist kein Objekt, und kann folglich auch nicht an eine Methode übergeben werden.
    Grässlicherweise geht das aber trotzdem, und deshalb hat ausnahmslos jeder im Verlaufe des Erlernens von VB.Net tierische Schwierigkeiten, zu kapieren, was da der Unterschied ist.
    Zwischen Datentyp und Objekt (erstellt aus einem Datentyp, mit dem Schlüsselwort New).
    Diese Formulierung hingegen: ShowMdiChild(My.Forms.DatentypName) kann hingehen, denn man sieht: Was da als DatentypName steht, kann kein Datentypname sein, sondern ist eine Property von irgendwas (nämlich von My.Forms - was immer das wiederum auch ist).
    Und ist somit ein Objekt (was leider denselben Namen hat wie ein bekannter Datentyp, aber seisdrum).
    Da ist nichts doppelt gemoppeltes dran.
    Die eine Formulierung ist widersinnig (sieht widersinnig aus, aber voll), die andere folgt der syntaktischen Logik der Programmiersprache.



    tragl schrieb:

    Naja, der wird automatisch gebunden
    Fein - dann weisst du das jetzt ja auch: Das Automatische Binden baut bei Comboboxen Bockmist.

    tragl schrieb:

    Suchfenster als Dialog ... Wär das über DialogResult lösbar, dass er z.B. den bs.Current übernimmt?
    Das DialogResult sagt dir, ob der Dialog ausgewertet werden soll oder nicht.
    Wenn ja musste halt iwas coden, dass die BindingSource zum richtigen Datensatz hüpft.
    Wenn ein Datensatz readonly sein soll, kannste die Controls alle auf ein Panel legen, und das Panel auf Enabled=False setzen - das ist die einfachste Art, viele Controls gemeinsam zu enablen/disablen.
    Sieht aber u.U. scheisse aus - aber probier erstma.
    ZB Richtextbox kann readonly besser aussehen als Textbox - Textbox ist da'n bischen einfach gestrickt - wies bei die anderen Controls ist weiss ich nicht.

    Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    Die eine Formulierung ist widersinnig (sieht widersinnig aus, aber voll), die andere folgt der syntaktischen Logik der Programmiersprache.

    Ok, verstanden :)

    ErfinderDesRades schrieb:

    Fein - dann weisst du das jetzt ja auch: Das Automatische Binden von Comboboxen baut Bockmist.

    Jupp!

    ErfinderDesRades schrieb:

    Das DialogResult sagt dir, ob der Dialog ausgewertet werden soll oder nicht.
    Wenn ja musste halt iwas coden, dass die BindingSource zum richtigen Datensatz hüpft.
    Wenn ein Datensatz readonly sein soll, kannste die Controls alle auf ein Panel legen, und das Panel auf Enabled=False setzen - das ist die einfachste Art, viele Controls gemeinsam zu enablen/disablen.
    Sieht aber u.U. scheisse aus - aber probier erstma.
    ZB Richtextbox kann readonly besser aussehen - Textbox ist da'n bischen einfach gestrickt - wies bei die anderen Controls ist weiss ich nicht.

    Ah - guck dir nochmal die BindingSource-Properties an!

    Ich werd's probieren.


    Bin grad noch dabei die ChildForms in einem TabControl anzeigen zu lassen (damit ich zwischen den Childs wechseln kann).
    Der Code stammt von hier: codeproject.com/Articles/17640/Tabbed-MDI-Child-Forms
    Hab ich auch alles auf VB umschreiben können, einzig mit der .FormClosed komm ich nicht weiter

    Quellcode

    1. this.ActiveMdiChild.FormClosed +=
    2. new FormClosedEventHandler(
    3. ActiveMdiChild_FormClosed);


    Wie müsste der sinnvollerweise in VB.net lauten?

    EDIT: Mir würde es auch genügen, wenn er folgendes macht:
    - Einen Button auf der Menuleiste oder direkt darunter erzeugen wenn ich ein MdiChild aufrufe
    - den besagten Button wieder löschen wenn ich die MdiChild schließe
    - klick auf den erzeugten Button wechselt zum MdiChild

    Mit dem TabControl säh es so aus:
    mit Buttons könnte das so aussehen:

    wobei mir das mit den TabPages sinnvoller und hübscher erscheint
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „tragl“ ()

    Hier - für deine Link-Sammlung: converter.telerik.com/

    das mitte BindingSource-Props warnix - die sehen vielversprechend aus, sind aber readonly. (aber angucken ist trotzdem nützlich).

    dieser c#-code wird mittm vb-Schlüsselwort Addhandler übersetzt

    VB.NET-Quellcode

    1. Addhandler Me.ActiveMdiChild.FormClosed, ActiveMdiChild_FormClosed

    Kann man aber auch anners machen, zB mitte Handles-Klausel

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

    ErfinderDesRades schrieb:

    Hier - für deine Link-Sammlung: converter.telerik.com/

    Den Converter hatte ich benutzt, kam aber nix brauchbares bei raus.

    Was wäre denn hier der sender und was e in Zeile 12 in den Klammern von MdiClose()?
    Ist vermutlich schon zu spät, ich mach' morgen weiter. Eine passende Handles-Klausel für die MdiChilds hab ich nicht gefunden.

    Das Anlegen der Tabs klappt, auch das switchen funzt :) - allerdings habe ich z.B. "Stammdaten Mitarbeiter" bereits geöffnet (TabPage ist generiert worden) und möchte die
    unsinnigerweise erneut über den Tree öffnen, dann wechselt der Tab oben nicht mit - geöffnet wird dennoch nur eine Instanz davon (zum Glück! :) )

    VB.NET-Quellcode

    1. Private Sub MdiOpen(sender As Object, e As EventArgs) Handles Me.MdiChildActivate
    2. If Me.ActiveMdiChild Is Nothing Then
    3. tabMdi.Visible = False
    4. Else
    5. Me.ActiveMdiChild.WindowState = FormWindowState.Maximized
    6. Dim tp As New TabPage(Me.ActiveMdiChild.Text)
    7. If Me.ActiveMdiChild.Tag Is Nothing Then
    8. tp.Tag = ActiveMdiChild
    9. tp.Parent = tabMdi
    10. tabMdi.SelectedTab = tp
    11. Me.ActiveMdiChild.Tag = tp
    12. AddHandler Me.ActiveMdiChild.FormClosed, MdiClose()
    13. ' this.ActiveMdiChild.FormClosed +=
    14. 'New FormClosedEventHandler(
    15. 'ActiveMdiChild_FormClosed);
    16. End If
    17. If Not tabMdi.Visible Then tabMdi.Visible = True
    18. End If
    19. End Sub
    20. Private Sub MdiClose(sender As Object, e As FormClosedEventArgs)
    21. TryCast(TryCast(sender, Form).Tag, TabPage).Dispose()
    22. End Sub
    23. Private Sub MdiActivate(sender As Object, e As EventArgs) Handles tabMdi.SelectedIndexChanged, Me.MdiChildActivate
    24. If tabMdi.SelectedTab IsNot Nothing AndAlso tabMdi.SelectedTab.Tag IsNot Nothing Then TryCast(tabMdi.SelectedTab.Tag, Form).Select()
    25. End Sub

    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Guten Morgen. Das liest sich doch mal gut. Ich bastel nachher mal noch ein bisschen und häng dir das nochmal an. Ich will noch versuchen nen close „X“ auf die Tabs zu zaubern :) Kannst ja dann mal schauen ob das sich so gut macht wenn du Interesse hast :)



    Gibt's eine Möglichkeit das Feld StandortID im DGV in Standortname zu ändern? Also dass er mir den Standortnamen aus der Tabelle "Standort" anzeigt, anstelle der ID?
    Oder muss ich dazu ein weiteres Feld in die Tabelle hinzufügen, welches auf Standortname verweist?

    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

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

    ErfinderDesRades schrieb:

    naja - editiere halt die dgv-Spalten - setz die Properties wie wolle.

    Naja, das ist zumindest für mich einfacher gesagt als getan. In der Tabelle "Fahrzeug" wird nur die "Standort.ID" in Relation gesetzt.
    Gibt's da nen "Trick", ohne in der Tabelle "Fahrzeug" noch das Feld Standortname hinzuzufügen?

    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

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