DataGridViewComboBoxColumn - Listeneinträge deaktivieren

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von gonzo16.

    DataGridViewComboBoxColumn - Listeneinträge deaktivieren

    Hallo allerseits,

    ich habe mal wieder ein Problem mit einem datengebundenen DatagridView. Eine Spalte davon ist eine ComboBoxColunm, wo die Namen von Arbeitern (aus der DB) ausgewählt werden können. Ich möchte jetzt verhindern, dass der selbe Name mehrmals ausgewählt werden kann (siehe Screenshot). Am liebsten wäre mir, wenn ein bereits verwendeter Name in der Liste deaktiviert (ausgegraut), also nicht mehr auswählbar ist.
    Geht so was überhaupt, da die Grundlage der Liste ja eine Tabelle in der DB ist? Wie würdet ihr so was machen?

    Danke
    Gonzo
    Bilder
    • ScreenShot001.jpg

      22,11 kB, 472×395, 180 mal angesehen
    Danke für den Link. Allerding macht er das bis zum Post 11 ohne Databinding, also nicht das was ich brauche. Und danach gehts dann voll ins tiefe OOP und das ist wahrlich nicht meine Stärke, jedenfalls noch nicht. Ich werde mir das mal in Ruhe anguggen, im Moment blicke ich da noch nicht so recht durch.

    Außerdem reichts mir auch nicht, wenn Einträge aus der Liste nur entfernt werden. Bei mir müssen sie auch wieder hinzugefügt werden, falls nämlich die Zeile mit einem Arbeiter wieder gelöscht wird, muss der Name wieder in der ComboBox auswählbar sein.
    Na ja, jedenfalls scheint das alles recht kompliziert zu werden. Mal sehn, wie ich da weiterkomme.
    Mal sehen, ob ichs richtig verstehe:
    Du hast eine Tabelle, in der für jeden Arbeiter iwas eingetragen werden soll. Aber für jeden dieser Abeiters nur 1 mal. Das ist, wenn ich mich nicht irre eine 1:1-Beziehung. Also gibs nur so viele Datensätze wie Abeiters.
    Ergo isses eigentlich nur eine zusätzliche Spalte in deiner ArbeiterTabelle. Denn bräuchste auch keine Comboboxcolumnbumsdings, eigentlich.

    Fiel Fergnügen

    Vatter
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    @Vatter
    Nee, is keine 1:1 sondern 1:n Beziehung.
    Die Namen kommen aus der Personal-Tabelle (1 Satz pro Arbeiter). Gespeichert wird in der Arbeits-Tabelle. Hier werden täglich die Arbeitsstunden jedes Arbeiter gespeichert. Folglich kommt dort jeder Arbeiter mehrfach vor, aber eben nur ein mal pro Tag.

    Der Screenshot ist nur ein Ausschnitt aus dem ganzen Formular. Dort werden neben den Arbeitern mit ihren Stunden auch andere Daten (Arbeitsort, Datum, etc.) erfasst. In diesem Formular gibts dann auch noch andere (ähnliche) DGV's für den Maschineneinsatz und Werkzeugeinsatz. Damit hab ich das selbe Problem. Eine Maschine darf pro Tag auch nur einmal ausgewählt werden.
    Mir scheint eine m:n - Relation dahinterzustehen: Es gibt ArbeitsTage und Arbeiter, und es muß eine Mittler-Tabelle geben, die einem Arbeiter an einem Tag eine Arbeitszeit zuordnet

    Arbeiter->TagesArbeit<-Arbeitstag.

    Da würde ich kein DGV mit hinzufügezeile präsentieren, sondern für einen ArbeitsTag werden einfach für jeden Arbeiter ein Tagesarbeits-Datensatz generiert, und 0 ARbeitsstunden eingetragen.

    Diese Datensätze werden angezeigt, und für jeden Arbeiter kann seine Tagesarbeitszeit eingetragen werden, aber es kann nicht zugefügt oder gelöscht werden, oder ein Arbeiter ausgesucht oder was.

    ErfinderDesRades schrieb:

    Mir scheint eine m:n - Relation dahinterzustehen: Es gibt ArbeitsTage und Arbeiter, und es muß eine Mittler-Tabelle geben, die einem Arbeiter an einem Tag eine Arbeitszeit zuordnet

    Arbeiter->TagesArbeit<-Arbeitstag.
    Personnel --> TasksPersonnel (1:n)
    Tasks --> TasksPersonnel (1:n)

    Personnel: Tabelle mit Personaldaten
    Tasks: Arbeitsdatum, Feld, Feldfrucht, etc.
    TasksPersonnel: TaskID, PersonnelID, PersonnelHrs

    In der Tat, ist ne m:n Beziehung mit TasksPersonnel als Mittler-Tabelle. Man kann eben einem Profi ein X fürn U vorgaukeln ;). Ich habs vereinfacht beschrieben, weil es für den Post von Vatter nicht von Bedeutung ist, obs 1:n oder m:n ist, jedenfalls ist es kein 1:1.

    ErfinderDesRades schrieb:

    Da würde ich kein DGV mit hinzufügezeile präsentieren, sondern für einen ArbeitsTag werden einfach für jeden Arbeiter ein Tagesarbeits-Datensatz generiert, und 0 ARbeitsstunden eingetragen.
    Daran hab ich auch schon gedacht. Das würde auch dem Wunsch des Users entsprechen, da der vorher mit seinen Excel-Sheets genau so gearbeitet hat. Immer mit ner kompletten Liste und dann wurden bei den arbeitenden Leuten die Stunden eingetragen, die anderen kriegen ne 0. Allerdings gefällt mir das aus verschiedenen Gründen nicht:

    1. Die Listen werden täglich u.U. mehrfach täglich ausgefüllt. Es stehen ca. 50 Namen in der Arbeiter Tabelle. Davon sind 90% Aushilfskräfte, die nur zur Erntezeit (und auch dann selten mehr als 15-20) wirklich im Einsatz sind. D.h. es werden massenweisen leere/unnütze Datensätze gespeichert.
    2. Es erschwert den Umgang mit Agregatfunktionen (z.B. Mittelwert, Anzahl, etc.) weil man hier dann immer aufpassen muß, das die 0-Stunden-Sätze nicht mit verarbeitet werden.
    3. Neben der Arbeiter Tabelle gibt es identische Tabellen und Beziehungen für Maschinen, Fahrzeuge, Ackergeräte und Werkzeuge. Und da ist die Anzahl fast unübersehbar (z.B. sind ca. 140 Werkzeuge erfasst), aber im Einsatz sind immer nur sehr wenige. Insbesondere in den Zeiten mit wenig Arbeit, gehen 1 oder 2 Leute mit 1 oder 2 Maschienen/Werkzeugen aufs Feld. Daher widerstrebt es mir irgendwie, da immer die kompletten Listen anzubieten.
    Na ja, mal sehen wie ich das vernünftig gelöst kriege. Für Ideen und Vorschlägen bin ich jedenfalls immer offen.

    gonzo16 schrieb:

    D.h. es werden massenweisen leere/unnütze Datensätze gespeichert.
    die zu löschen ist das einfachste.

    ich denke, die benutzbarkeit ist besser, wenn alle Arbeiter in einer Tabelle präsentiert werden, statt dass man da sich den jeweiligen Arbeiter auf einer Combobox raussuchen muß.
    Da kannman auch noch jede menge schnickschnack mittm gui treiben, zb sowas wie Favoriten.
    Also dass man bestimmen kann, welche arbeiter man zeitweise ausblenden möchte, und dann hat man einen Button auch für "alle anzeigen" oder sowas.
    Hmm, was du da mit der GUI vorschlägst ist einleuchtend und kling verlockend. Gut, mit 20-50 Arbeitern wäre das sicher machbar. Aber wie würdest du das mit 140 Werkzeugen machen? Auch alle auflisten? Und das andere Zeuch auch?
    Und wie soll ich das alles auf ne Form packen? Die ist ja jetzt schon mit den DGV's und den anderen Controls rabenvoll. Dazu kommt, das der User net scrollen will. Er sagt, dass er sonst Sachen übersieht. Ist zwar Unsinn, denn in den Excel-Sheets hatter vorher auch scrollen müssen, aber naja... :wacko:

    Na, man merkt sicher an den Fragen, dass ich ein grottenschlechter Designer bin :D.

    Im Moment hab ich das folgendermassen gelöst: Das ganze Zeuch (Arbeiter, Maschienen, etc.) wird in DGV-ComboColumns ausgewählt. Arbeitsstunden und andere Infos werden in weiteren DGV-Spalten eingegeben. Weil sich innerhalb bestimmter Zeiten (z.B. Erntezeit) bestimmte Arbeiten und damit auch der Arbeitskräfte/Machienen/etc. Einsatz täglich wiederholt und der User nicht täglich die selben 20 Leute und Traktoren und Werkzeuge usw. aus der ComboBox rauspicken will (verständlicherweise!!), hab ich der Form nen Button "Load Previous Values" spendiert. Damit wird schlicht die komplette Form mit allem drum und dran mit den Daten des letzten gespeicherten Datensatzes gefüllt und als Datum der heutige Tag eingesetzt. Damit kann der User i.d.R. direkt auf "Speichern" klicken und fertig. Bzw. wenn ein Arbeiter heute nicht da war, muss nur die betreffende Zeile im DGV gelöscht werden.
    Das nicht der selbe Arbeiter mehrfach ausgewählt werden kann verhindere ich, indem ich im SelectedIndexChanged erstmal prüfe ober der SelectedText im DGV schon vorhanden ist und wenn ja, wird der SelectedIndex einfach auf -1 gesetzt. Damit wird der Arbeiter nicht im DGV eintragen. Der Schönheitsfehler an der Sache ist nur, dass der Name in der Liste der ComboBox ganz normal dargestellt wird. Damit wird dem Benutzer suggeriert, er könne den Name wählen. Schöner wäre es halt, wenn der Name in der Liste grau dargestellt wird (oder gar nicht erscheint).

    Daher meine Frage. Ich hatte auch net gedacht, dass das sooo kompliziert ist. Aber was ich bisher dazu recherchiert hab (inkl. den Link von SystemUnknow) will mir einfach nicht in die Birne. Irgendwie hab ich bei OOP ein Brett vorm Kopf. Naja, vielleicht werfe ich ja doch die ganze Forrm noch mal übern Haufen und machs mit Listen. Dazu muß ich aber erst mal auf ein halbwegs praktikables Design kommen. Ist sowieso nur ne Fleißaufgabe, denn dat Ding läuft ja soweit und andere Sachen sind im Moment wichtiger.
    Jo, LoadPreviousValue gfällt mir eiglich sogar besser als LoadAllWorkers :thumbup:

    ich täte übrigens nicht SelectedText gegen Cells.Value abgleichen, sondern .SelectedValue mit dem Inhalt der BindingSource.

    Am DropDown kannman schon herummanipulieren - es handelt sich ja um eine normale Combobox. Die muß man im DGV_EditingControlShowing abgreifen, und mit einer individuellen, aber kompatiblen DataSource versehen.

    ach mannoo!

    habichdoch schon drauf verlinkt: einfache Lösung

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

    Man kann auch iwie mehrere Spalten gleichzeitig Unique setzen.
    Wenn z.B. Datum und Mitarbeiterspalte als gemeinsamer Schlüssel gelten, ist es nicht möglich mehrere Datensätze mit identischem Mitarbeiter UND Datum zu erzeugen. Da gibs ne Exception, die man auswerten kann und springt dann einfach auf den schon vorhandenen Datensatz. Der Benutzer merkt davon praktisch nüscht, nur dass eben der vorhandene Datensatz angezeigt, markiert oder sonstewas wird.

    Fiel Fergnügen

    Vatter
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    @EDR: Ist ein Super-Tipp. Genau das was ich suchte :thumbsup: .

    Ich habe bei meinen Recherchen in den letzten Tagen noch ein paar andere, sehr interessante, Seiten gefunden. Besonders diese hier gefällt mir sehr gut. Der gepostete Code enabled/disabled ComboBoxItems. Die beschriebenen Bugs werden etwas weiter unter durch die Ergänzungen gefixt (bis auf das Keyboard Problem). Jedenfalls könnte ich damit gut leben.

    Da ich jedoch ein völliger OOP-Noob bin hab ich doch tatsächlich einige Fragen dazu :whistling:. Ich hoffe, das ihr euch die Mühe macht und da mal reinschaut. Ist nicht allzuviel Code und selbst ich verstehe davon das meiste.

    Die Erste:

    VB.NET-Quellcode

    1. MyCombo1.Items.Add(New ComboBoxItem("Rot", True))
    2. MyCombo1.Items.Add(New ComboBoxItem("Grün", True))
    3. MyCombo1.Items.Add(New ComboBoxItem("Blau", False))
    4. MyCombo1.Items.Add(New ComboBoxItem("Gelb", True))
    5. MyCombo1.Items.Add(New ComboBoxItem("Lila", False))
    6. MyCombo1.Items.Add(New ComboBoxItem("Pink", True))

    Damit lassen sich zwar wunderschön die ComboItems beim füllen der ComboBox aktivieren/deaktivieren. Aber wie kann man den Zustand später noch mal wechseln? Die Items werden als eigene Objekte instanziert, aber wie greife ich da später gezielt drauf zu?

    Die Zweite:
    Mit dem geposteten Code habe ich mir ein neues Control erzeugt, welches ich über die Toolbox auf eine Form packen kann. Wie krieg ich das aber hin, eine DataGridViewComboBoxColumn mit dem Code zu manipulieren? Oder anders gefragt: Was muß ich machen um das Standardverhalten der DGVComboColumn zu ändern (bitte genaue Schritt-für-Schritt-Anleitung für Dumme).

    Ich sach schoma Danke :love: an alle Helfer.