Parameterübergabe an Prozedur einschränken

  • VB.NET

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von cl10k.

    Parameterübergabe an Prozedur einschränken

    Basierend auf der ComboBox habe ich ein UserControl erstellt, dass noch ein bisschen zusätzlichen Schnickschnack bereitstellt.

    Das Usercontrol besitzt ein eigenes Bindingsource; die ComboBox wird im Endeffekt an eine DataTableColumn eines DataSets gebunden.

    Es existiert eine kleine Methode um dem UserControl die nötigen Infos für die ComboBox zu geben:

    VB.NET-Quellcode

    1. Public Sub Test(ByVal tmpDataTable As DataTable, ByVal tmpDataTableColumnName As String)
    2. If tmpDataTable.Columns.Contains(tmpDataTableColumnName) Then
    3. BindingSource.DataSource = frm_Main.SPOK_DataSet
    4. BindingSource.DataMember = tmpDataTable.TableName
    5. CmbBx_Input.DataSource = BindingSource
    6. CmbBx_Input.DisplayMember = tmpDataTableColumnName
    7. CmbBx_Input.ValueMember = tmpDataTableColumnName
    8. Else
    9. MsgBox("ColumnName ungültig")
    10. End If
    11. End Sub


    Es stört mich, dass der Columnname als String übergeben wird. Ich habe zwar diese kleine If-Schleife die sicherstellt, dass dieses Column auch tatsächlich existiert, aber das ist trotzdem doof.

    Wie kann man den Parameter zur Festlegung der DataTableColumn umformulieren, damit ich quasi schon bei der Parameterübergabe eine Auswahl der tatsächlich in tmpDataTable vorhandenen Colums habe (also ähnlich wie bei der Verwendung von enums)?

    (An den eigentlichen Namen komme ich dann ja wieder mit Columnname heran, sodass DisplayMember und ValueMember dann doch noch ihren String bekommen.)



    Sinngemäß stelle ich mir das so vor:

    VB.NET-Quellcode

    1. Public Sub Test(ByVal tmpDataTable As DataTable, ByVal tmpDataTableColumn As DataColumn in tmpDataTable)
    2. ...
    3. End Sub


    Geht das überhaupt?

    lg

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „cl10k“ ()

    Hmmm, ich habe wohl ein Brett vorm Kopf - im Objectbrowser konnte ich nichts finden was mir so direkt als Lösung ins Auge springt.

    Vielleicht war meine Fragestellung auch nicht eindeutig und wir reden aneinander vorbei:

    Ich möchte beim Aufruf der Prozedur, nachdem ich den ersten Parameter tmpDataTable eingegeben habe, für den zweiten Parameter eine Einschränkung auf die tatsächlich vorhandenen DataColumns erreichen.

    Sry, aber bisher hat es noch nicht Klick gemacht... :S
    ja, und was brauchst du, um dein Binding einzurichten?
    Doch eine DataTable und einen ColumnNamen.
    Ja - ist doch gegeben - guck die Properties doch an.

    Also brauchst du nur eine DataColumn an deine Funktion zu übergeben, und daraus kann die sich alles fürs Binding notwendige holen :D
    Ahh jetzt verstehe ich. Also haben wir in gewisser Weise doch aneinander vorbei geredet.

    Mir als Urheber des Programms kann es im Endeffekt egal sein, wie umständlich die Parameterübergabe ist. Mein Gedanke galt den armen Hunden die irgendwann mein Programm mal erweitern sollen und dabei Gebrauch von diesem UserControl machen wollen. Ich hielt es für intuitiver, wenn Derjenige der Prozedur den DataTable übergibt und dann als zweiten Parameter eine Auswahl aus den tatsächlich vorhandenen Columns.


    Bei der von dir vorgeschlagenen Lösung müsste der Anwender dann ja nicht mehr nur Kenntnisse der vorhandenen DataTables haben sondern sogar noch eine Ebene tiefer und wissen welche Columns in den x Tables vorhanden sind und ich muss dann trotzdem prüfen, ob diese Column in einem Table im DataSet auch wirklich vorhandenen ist, oder übersehe ich immer noch etwas?


    Sollte ich es hingegen immer noch nicht begriffen haben, darfst du auch gern grob werden... ;)

    Ich werde aus Gründen der Einfachheit aber auf deinen Vorschlag zurückgreifen - ein einziger Übergabeparameter ist besser als zwei... Danke!

    lg

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

    cl10k schrieb:

    und ich muss dann trotzdem prüfen, ob diese Column in einem Table im DataSet auch wirklich vorhandenen ist
    Es kann nicht vorkommen, dass eine DataColumn nicht in irgendeiner DataTable vorhanden ist. Und ebensowenig kann der ColumnName ungültig sein, daher sind keine Üprüfungen notwendig, und müsste also so gehen:

    VB.NET-Quellcode

    1. Public Sub Test(ByVal column As DataColumn)
    2. BindingSource.DataSource = column.Table
    3. CmbBx_Input.DataSource = BindingSource
    4. CmbBx_Input.DisplayMember = column.ColumnName
    5. CmbBx_Input.ValueMember = column.ColumnName
    6. End Sub
    Falls der User es wirklich zuwege bringt, deim UserControl eine Column aus einem falschen Dataset anzudrehen, so zeigt dein Control eben Daten aussm falschen Dataset an - da kannman nix machen (und muß man auch nicht).

    Dieses hier

    cl10k schrieb:

    VB.NET-Quellcode

    1. BindingSource.DataSource = frm_Main.SPOK_DataSet
    ist ein Gräuel in mehrfacher Hinsicht (Verwechslung von Klasse und Objekt, sowie zu enge Kopplung).
    gugge VeryBasics

    cl10k schrieb:

    Du spielst darauf an, das ich das Standardformular nicht instanziert habe?
    Anspielung?
    Ich sage ganz genau, wassich meine:
    • Der Code verwechselt offensichtlich Klasse und Objekt
    • dein userControl wird dadurch an frm_Main gekoppelt, was u.U. nicht nötig wäre (hier aber vlt. auch nicht schadet, denn du willst es eh nirgends sonst verwenden)
    Hast du VeryBasics nachgelesen?
    Ich muss bevor wir zur eigentlichen Lösung kommen noch ein bisschen rumbohren. :)

    VB.NET-Quellcode

    1. Der Code verwechselt offensichtlich Klasse und Objekt


    Diese Besonderheit das vb.net den Nutzer nicht "zwingt" ein Standardform zu instanzieren sondern stattdessen erlaubt, diese Forms wie statische Klasse zu verwenden?

    Ich komme gleich zu meiner konkreten Frage, ich will nur sicherstellen das ich verstehe worum es hier grad geht...


    PS: Den Basics Link lese ich alle drei Tage und mit jeden Lernfortschritt begreife ich ein bisschen mehr was dort steht und was die Konsequenzen sind... Aber ich bin halt langsam (das Alter ;) )

    cl10k schrieb:

    Diese Besonderheit das vb.net den Nutzer nicht "zwingt" ein Standardform zu instanzieren sondern stattdessen erlaubt, diese Forms wie statische Klasse zu verwenden?
    Ja, diese Besonderheit Absonderlichkeit.

    Auf die Idee, das mit einer statischen Klasse zu vergleichen binnich noch nichtmal gekommen - hat tatsächlich Ähnlichkeiten. Aber auch Unterschiede.

    Es ist auf jeden Fall Crap vom Feinsten, und sollte in einem UserControl nicht genutzt werden.

    Stell dirmal vor, du öffnest von deiner MainForm-Klasse mal spasseshalber 2 Stück - ich wette, du kannst nicht abschätzen, wie sich dann dein ucl verhält.

    Probiers einfach mal aus :)
    Ja, mir ist diese Problematik durchaus bewusst. Generell instanziere ich Forms wenn ich diese erst später verwende. Nur bei Mainform (aka Form1) weiss ich nicht wie.

    Mein Projekt erwartet ein StartupForm. Ich finde es merkwürdig erst irgenein Form als Startup zu verwenden und dann im Anschluß eine Instanz meines eigentlichen Forms zu laden.
    Generell finde ich es merkwürdig das mein Rahmenprogramm (also das was bei C main sein müsste?) ein Form ist. Viel eher würde ich dort "formlosen" Code erwarten und gezielt dort an geeigneter Stelle erst mein gewünschtes Form laden. Ist der Gedanke verständlich?
    also hier kannichdir folgen, weil in c# ist das prinzipiell so umgesetzt, unds gibt garnix anneres: Void Main, der Einsprungspunkt der Anwendung ist eine Methode ("formlos"), und innerhalb dieser wird das MainForm mit New instanziert, und anschließend angezeigt.
    VB ist da scheinbar einfacher (nämlich für vb6-noobs), und in Wirklichkeit komplizierter, und mitte DefaultForm-Instanz schlagense halt dem Fass die Krone ins Gesicht :cursing:

    Den Gräuel kannst du beheben, indem du dein userControl konsequent als SubObjekt auffasst, welches seinen Owner nicht kennt (ob das nun eine frm_Main-Instanz ist oder whatever).
    Das ucl kennt kein frm_Main, und im in post#8 gegebenen Code ist ja auch gezeigt, dass die BindingSource auch ohne das frm_Main zu kennen sich eine DataSource holen kann - eben aus der DataColumn, die hereingereicht wird.

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

    OK! Das Konzept habe ich verstanden und werde es umsetzen! Keine Verweise auf den Owner bzw. keine Verweise auf in der Hierachie übergeordnete Objekte

    Es bleibt dann aber noch die Frage, in welchem Rahmen ich mein MainForm instanziere? Derzeit ist es ja noch eine "Klasse". (Dieser Aspekt verwirrt mich sehr, zumal Rod und du es immer wieder anmerken...)

    EDIT zu deinem EDIT: Was nehme ich als VOID MAIN und wie sage ich dem Projekt das es damit starten soll?

    PS: Sry für die lange Leitung. Irgendwann wird es hoffentlich mal besser (und vielleicht profitieren andere Anfänger auch von meinen Fragen :whistling: )

    cl10k schrieb:

    Es bleibt dann aber noch die Frage, in welchem Rahmen ich mein MainForm instanziere?
    Wassn fürn Rahmen?
    Vb instanziert für dich eine Instanz davon, und zeigt die an, das kannste nicht ändern (doch kannsteschon, wennde gerne exotisch programmierst).
    Ich jdfs. würde das so lassen, weils halt das übliche ist.

    cl10k schrieb:

    Was nehme ich als VOID MAIN und wie sage ich dem Projekt das es damit starten soll?
    das war nur der Vergleich mit c#. Ich empfehle nicht, nun vb.net zu programmieren wie c#.

    cl10k schrieb:

    Keine Verweise auf den Owner bzw. keine Verweise auf in der Hierachie übergeordnete Objekte
    Dassis der Punkt, und sonst nix. :thumbsup: