Announcement

Collapse
No announcement yet.

MaskedTextbox - dynamische Zuweisung

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • MaskedTextbox - dynamische Zuweisung

    Ich möchte meine Form dynamisch aufbauen. Das heißt, unsere Kunden verwalten Ihr Equipment sehr unterschielich und so ergeben sich unterschiedliche Schlüsselformate.
    Die Maske der verschiedenen Formate verwalte ich in einer Initialisierungstabelle, welche zur Laufzeit (Load_Event) ausgelesen wird)

    Dann soll die Zuweisung per

    Me.controls("meinFeld").Mask bzw. Me.contols("meinFeld").Property("Mask")
    erfolgen.

    Ich habe vorher viel in Access programmiert und da hatte ich es mit

    Forms(Form).Controls(uform).Controls(ctl).Properti es(prop) gut lösen können.

    Die Form,uform,ctl und prop hatte ich in der benannten Init-Tabelle. Die habe ich dann mit einem Cursor durchlaufen.
    Eine ähnlich Lösung möchte ich in VB2008 aufbauen.


    Wenn ich nun ein Textfeld als MaskedTextbox (Name=mbt1) in meine Form aufnehme kann ich hart

    [highlight=vbnet]Me.mtb1.Mask = ">L" [/highlight]
    zuweisen.
    Bei einem Aufruf
    [highlight=vbnet] Me.controls("mtb1").Mask = ">L" [/highlight]

    kommt aber der Fehler: "mask" ist kein Member von "System.Windows.Forms.Control"

    Und da habe ich noch gar nicht versucht, auch die Eigenschaft dynamisch zu übergeben.

    Vielen Dank vorab für die Unterstützung

    mfg dbfreak

  • #2
    kommt aber der Fehler: "mask" ist kein Member von "System.Windows.Forms.Control"
    Aus 'Me.controls("mtb1")' kommt, wenn etwas gefunden wurde, ein Control zurück oder eben null.

    Also solltest du

    1. prüfen ob auch was gefunden wurde
    2. prüfen ob das gelieferte Control vom richtigen Typ ist
    3. das gelieferte Control dann in den gewünschten Typ casten
    4. dann erst eine Methode oder Property auf diesem gecasteten Control aufrufen

    Comment


    • #3
      Hallo Ralf J,,

      vielen Dank für Deine schnelle Antwort. Leider bringt mich das noch nicht richtig weiter. Hast Du vielleicht ein Codebeispiel.

      danke vorab

      Comment


      • #4
        Bevor ich da weiterhelfe solltest du uns mehr deines Codes zeigen insbesondere wie die Controls die du per Name ansprechen willst erzeugt werden.

        Üblicherweise ist es der falsche Weg per Namen auf ein Control zuzugreifen, insbesondere dann wenn man glaubt (möglicherweise du auch) das der Name eines Controls das selbe ist wie ein Variablenname auf das Control.

        Comment


        • #5
          Was genau verstehst Du denn nicht? Ich finde Ralf hat es gut beschrieben. Das ist absolute Programmierbasis.

          Comment


          • #6
            Hallo Ralf J.,

            also meine Controls erzeuge ich ganz normal über den Designer. Dort werden auch die Namen festgelegt. Und ja, ich wollte über den vergebenen Namen dann auf dieses Control Zugreifen.
            In meiner Initialisierungstabelle habe ich dann den Namen des Controls, den Namen der Form, den Namen des Kundenprojektes,die zu ändernde Eigenschaft und den Wert der neuen Eigenschaft hinterlegt.
            Beim Loadereignis arbeite ich dann die Zeilen der Maske für das entsprechende Kundenprojekt (wird beim anmelden an die Applikation gesetzt) ab.
            Für normale Textfelder, Labels funktioniert das auch prima. Anbei mein Codeausschnitt.

            [highlight=vbnet]

            cmd.Connection = con
            cmd.CommandText = "SELECT id_pruefprotokoll, control, property, property_value, Description, Form, Folder, dbfield,Protokolltyp FROM tblinitpruefprotokoll where Protokolltyp=" & rep_id

            dr = cmd.ExecuteReader
            If dr.HasRows Then
            While dr.Read()
            parameter = dr.Item("control")
            p_value = dr.Item("property_value")
            Me.Controls.Item(parameter).Text = p_value

            End While
            End If
            [/highlight]

            Ich krieg eben nicht den Bogen zu den MaskedTextbox-Feldern.

            Im Designer wird das Teil wie folgt ausgewiesen
            [highlight=vbnet]
            Me.block = New System.Windows.Forms.MaskedTextBox
            Me.block.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.BS, "BLOCK", True))
            resources.ApplyResources(Me.block, "block")
            Me.block.Name = "block"
            Me.Controls.Add(Me.block)
            Friend WithEvents block As System.Windows.Forms.MaskedTextBox
            [/highlight]

            und sorry, wenn mir hier die Basis fehlt. Mein Spezalgebiet sind Datenbanken und ich bin am Lernen.

            Comment


            • #7
              Das liegt nicht explizit an der TextBox dass es dort funktioniert. Erstmal sind alle Controls in einer Benutzeroberfläche von Control abgeleitet. Das heisst ein Control hat IMMER eine Eigenschaft Text. Deswegen kannst Du diese oben auch setzen ohne zu wissen welches Control Du genau hast.
              Im Endeffekt heisst das Du setzt die Eigenschaft Text eines Control Objekts, nicht die Eigenschaft Text eines TextBox Controls. Ich hoffe Du verstehst was ich meine.

              Mask ist allerdings in Control NICHT definiert. Deswegen kannst Du die Eigenschaft auch nicht auf einem Objekt der Klasse Control setzen. Deswegen musst Du vorher das Item in eine MaskedTextBox umwandeln. Hierzu würde ich mir in der Datenbank eine neue Spalte hinzufügen in der der Typ des Controls festgehalten wird welches gesetzt werden soll. Dann kannst Du anhand des Datenbankeintrags erfragen um welchen konkreten Typ es sich bei deinem Control handelt und dieses entsprechend casten und den Wert dann setzen.

              Ich hoffe ich habe mich jetzt einigermaßen einsteigerfreundlich ausgedrückt.

              Comment


              • #8
                Für normale Textfelder, Labels funktioniert das auch prima. Anbei mein Codeausschnitt.
                Weil jedes Control eine Text Property hat (ist halt von Control geerbt). Wenn du dir aus der ControlCollection ein Control holst kannst du also immer auch Text setzen. Auch bei Controls wo das keinen Sinn macht (TabControl, Splitter etc.).

                Me.block.Name = "block"
                Das ist der Name des Controls. Wenn du das unbedingt über den Namen machen willst(oder mußt wegen einer schon vorhanden DB mit entsprechenden Daten) ist das der entscheidende Name. Es sollte aber glücklicherweise immer Variablenname gleich Controlname sein wenn du die Controls immer über den Winforms Designer erstellt hast.



                Im folgenden eine Beispiel Methode wie das in C# aussehen würde(Geht natürlich in VB genauso). Beim übersetzen in VB wirst du die Grundlagen nebenbei lernen. Bei Fehlern habe ich hier nur einen bool zurückgegeben in produktivem Code solltest du das durch werfen passender Exceptions ersetzen.

                [Highlight=C#]public bool SetValue(Control container, string controlName, string propertyName, object propertyValue)
                {
                // Control über Namen im Container suchen (mit Find um rekursic zu suchen)
                Control[] controls = container.Controls.Find(controlName, true);

                // checken ob auch was gefunden wurde
                if ((controls != null) && (controls.Count() > 0))
                {
                // für das erste gefunden Control die Property ranholen
                Control control = controls[0];
                PropertyInfo propertyInfo = control.GetType().GetProperty(propertyName);

                // checken ob auch eine entsprechende Property gefunden wurde
                if (propertyInfo != null)
                {
                // prüfen ob der Wert überhaupt dieser Property zuweisbar ist
                if (!propertyInfo.PropertyType.IsAssignableFrom(prope rtyValue.GetType()))
                return false;

                // Wert endlich zuweisen
                propertyInfo.SetValue(control, propertyValue, null);
                return true;
                }
                }

                return false;
                }[/Highlight]

                Aufruf zum Beispiel

                [Highlight=C#]SetValue(this, "mtb1", "Mask", ">L"); [/Highlight]

                Comment


                • #9
                  Hallo,

                  ja Du hast Dich verständlich ausgedrückt. Den Typ mit in die DB aufzunehmen halte ich für eine sehr gute Idee. Das vereinfacht die Sache dann erheblich.

                  Ich mach mich dran und melde dann hoffentlich meinen Erfolg.

                  mfg dbfreak

                  Comment


                  • #10
                    Je nach Anwendungsfall finde ich auch Ralfs Lösung sehr gut. Dort brauchst Du nichts extra in der Datenbank abspeichern.

                    Comment

                    Working...
                    X