none
Variable global bei clickevent schreiben RRS feed

  • Frage

  • Hi,

    ich bin relativ neu in der Powershell Welt und komme an einer Gewissen Stelle nicht weiter.

    Ich versuche etwas mit GUIs zu basteln. Jetzt ist mein Frage, ich habe ein Tastendruck Event und möchte damit eine Zahl oder ein Zeichen in eine Variable schreiben, sodass ich ihn außerhalb des Event aber noch verwenden kann.

    Ich habe schon einiges getestet, aber komme leider nicht weiter.

    #Fenster erstellen
    Add-Type -AssemblyName System.Windows.Forms
    $Form                    = New-Object system.Windows.Forms.Form
    $Form.ClientSize         = '500,300'
    $Form.text               = "TestGUI"
    $Form.BackColor          = "#ffffff"
    
    
    Add-Type -AssemblyName System.Windows.Forms
    [System.Windows.Forms.Application]::EnableVisualStyles()
    
    #Strukturen des Fensters
    $Form                            = New-Object system.Windows.Forms.Form
    $Form.ClientSize                 = New-Object System.Drawing.Point(400,400)
    $Form.text                       = "Form"
    $Form.TopMost                    = $false
    
    #Test1 Button
    $Test1                         = New-Object system.Windows.Forms.Button
    $Test1.text                    = "1"
    $Test1.width                   = 200
    $Test1.height                  = 200
    $Test1.location                = New-Object System.Drawing.Point(50,70)
    $Test1.Font                    = New-Object System.Drawing.Font('Microsoft Sans Serif',10)
    
    #Amazon Prime Button
    $Test2                     = New-Object system.Windows.Forms.Button
    $Test2.text                = "2"
    $Test2.width               = 200
    $Test2.height              = 200
    $Test2.location            = New-Object System.Drawing.Point(300,70)
    $Test2.Font                = New-Object System.Drawing.Font('Microsoft Sans Serif',10)
    
    #Disney+ Button
    $Test2                      = New-Object system.Windows.Forms.Button
    $Test2.text                 = "3"
    $Test2.width                = 200
    $Test2.height               = 200
    $Test2.location             = New-Object System.Drawing.Point(550,70)
    $Test2.Font                 = New-Object System.Drawing.Font('Microsoft Sans Serif',10)
    
    $Form.controls.AddRange(@($Test1))
    $Form.controls.AddRange(@($Test2))
    $Form.controls.AddRange(@($Test2))
    
    #Event nach Tastendruck
    $Test1.Add_Click({
       $auswahl = 1
    })
    
    $Test2.Add_Click({
       $auswahl = 2
    })
    
    $Test2.Add_Click({
        Write-Host $script:auswahl Test3
    })
    
    
    
    
    [void]$Form.ShowDialog()
    
    if($auswahl -eq "Test1")
    {
    echo("if1")}
    else
    {
    echo("else3")
    }

    Ich hoffe ihr könnt mir helfen.

    Dankeschön im vorraus.

    Grü0e


    Montag, 14. September 2020 10:08

Antworten

  • Hallo, Saiinox,

    sorry, bin etwas spät zur Off-Topic-Party und fasse meine Meinung zum Thema Powershell+GUI daher ganz kurz zusammen: Es eignet sich hervorragend. :-) Und sonst: Why GUIS are good...

    Ich hoffe du hast dein Problem bereits gelöst, aber falls nicht:

    "Der Suchende" hat schon richtig angedeutet, das du ein Scoping-Problem (about_scopes) hast, allerdings reicht es nicht die Variable am Anfang zu definieren.
    Danach könntest du sie zwar in den Funktionen und Events abrufen, aber beim Ändern oder Zuweisen von Werten erzeugst du eine neue lokale Variable mit dem gleichen Namen innerhalb der Funktion, die dann auch außerhalb nicht abrufbar ist.

    D.h. um innerhalb einer Funktionen (oder in deinem Fall in Events),  eine Variable zu ändern die auch außerhalb noch verfügbar sein soll, musst du die Variable explizit mit z.B. "$script:Auswahl = 1" ansprechen.

    Abgesehen davon, hast du deinen Button Test2 zweimal definiert und somit Button "2" mit "3" überschrieben.
    Die Abfrage am Ende:

    ($auswahl -eq "Test1")

    macht so auch keinen Sinn, da du $Auswahl nur die Zahlen 1 oder 2 zuweist.


    Blog: http://www.bytecookie.de

    Powershell Code Manager: Link
    (u.a. Codesnippets verwalten + komplexe Scripte graphisch darstellen)

    Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
    Warum das Ganze? Hier gibts die Antwort.

    Samstag, 26. September 2020 12:47
    Moderator

Alle Antworten

  • Ja, klar, man kann mit Powershell auch etwas Grafisches basteln. Aber sie ist nicht wirklich dafür gemacht und deshalb in dieser Beziehung auch alles andere als intuitiv. Warum sich gerade Anfänger so häufig mit GUI-Frickeleien beschäftigen, werde ich wohl nie verstehen.

    In der Konsole ist Deine Aufgabe mit einer Zeile Code erledigt:

    $variable = Read-Host -Prompt 'Bitte eine Zahl oder ein Zeichen eingeben'
    $variable
    Meine Empfehlung wäre, sich erstmal die Basics draufzuschaffen und die GUI-Basteleien auf später zu verschieben. ;-) 


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Montag, 14. September 2020 13:11
  • Warum sich gerade Anfänger so häufig mit GUI-Frickeleien beschäftigen, werde ich wohl nie verstehen.

    Ich hab da eine Vermutung :-) Ich denke, sie haben am Ende *noch* mehr Angst davor, etwas Kompiliertes mit VB.NET oder C# in die Welt herauszublasen, und dann nicht an Ort und Stelle debuggen zu können.

    Oder, wie gerade in meinem aktuellen Projekt, man hat in Produktion einfach nicht genug Internet-Zugang, um Visual Studio in Betrieb nehmen zu können...


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Montag, 14. September 2020 14:09
  • Ich denke, sie haben am Ende *noch* mehr Angst davor, etwas Kompiliertes mit VB.NET oder C# in die Welt herauszublasen, und dann nicht an Ort und Stelle debuggen zu können. ...

    Hmmm, ok, in die Richtung hatte ich bisher auch noch nicht gedacht. ;-) Man macht sich das Leben aber aus beiden Richtungen unnötig schwer, finde ich.

    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Montag, 14. September 2020 14:33
  • Oder zum Problem:
    Definiere einfach eine Variable am Anfang im Script. Die ist automatisch global und von überall ansprechbar solange du den Namen innerhalb einer Funktion nicht noch mal verwendest.

    Offtopic:

    Ob nun Powershell oder Access oder Excel. Man versucht sich immer wieder an z.T. komplexen GUI's auch für einfache Dinge weil es einfach netter aussieht und von Chefs gerne gefordert wird.
    Der Read-Host ist dazu auch nicht typ-sicher, da kann man auch alles andere als eine Zahl eingaben.
    Dies muss zusätzlich (RegEx) geprüft werden.
    Eine GUI ist da schon sicherer für den Enduser.

    Und was Debugging angeht, so liefere ich generell nur Debug-Versionen aus. Im Fehlerfall gibts das Protokoll des Callstacks und der Fehler ist meist so schneller gefunden.
    In anderen Szenarien wird man dann auch schon mal auf das perfekte Softwareframework hingewiesen, mit der selbst der Laie durch Regelimplementierungen alles machen können soll was zu jedwedem Problem passt um es zu lösen. Explizit wird darauf hingewiesen: Programmierkenntnisse oder gar Datenbankkenntnisse sind nicht nötig.

    Montag, 14. September 2020 20:09
  • Der Read-Host ist dazu auch nicht typ-sicher, da kann man auch alles andere als eine Zahl eingaben.

    Was heißt hier, nicht typ-sicher? Read-Host liefert immer zuverlässig einen String ;-) Oder, mit dem entsprechenden Parameter aufgerufen, einen SecureString...

    Evgenij Smirnov

    http://evgenij.smirnov.de

    Montag, 14. September 2020 21:06
  • Auflösung der Frage warum ich was mit GUI basteln will ist folgendes, anstatt Vodafone und sonstigen Anbietern monatlich zu Zahlen für das Serien streamen, möchte ich mir eine Kleinigkeit schrieben, damit ich per Raspberry pi und einer Fernbedienung mir eine kleine Streamingplatform erschaffen.
    Montag, 14. September 2020 22:08
  • Moin,

    die Verwunderung bezog sich nicht darauf, dass man 2020 noch was mit GUI basteln möchte ;-) sondern darauf, dass es *dann* trotzdem PowerShell sein soll. Skriptsprachen sind dafür naturgemäß weniger geeignet.


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Dienstag, 15. September 2020 06:42
  • Die SreamingPlattform hast du automatisch bereits durch den WindowsMedia-Player. Dieser ist im Netz als Mediaserver erreichbar.

    Ich habe mir vor Jahren eine WD-MyBook (3TB) zugelegt (€89). Die ist im Netz auch als Mediaserver verfügbar.
    Wenn du eine Fritzbox hast (hat ja heute fast jeder), schließe eine USB-Festplatte an und du hast mittels Fritzbox einen weiteren Mediaserver.
    Alle haben integrierte Suchfunktionen nach den bekannten Mediatags.

    Was brauchst du da mehr (außer es mal auprobiert zu haben)?

    Und was den String angeht: diesbezüglich hast du ja recht ein String bleibt ein String, aber es wird ja eine Zahl gefordert (oder mal ein Datum oder sonstwas).


    • Bearbeitet Der Suchende Dienstag, 15. September 2020 07:08
    Dienstag, 15. September 2020 07:06
  • Hallo, Saiinox,

    sorry, bin etwas spät zur Off-Topic-Party und fasse meine Meinung zum Thema Powershell+GUI daher ganz kurz zusammen: Es eignet sich hervorragend. :-) Und sonst: Why GUIS are good...

    Ich hoffe du hast dein Problem bereits gelöst, aber falls nicht:

    "Der Suchende" hat schon richtig angedeutet, das du ein Scoping-Problem (about_scopes) hast, allerdings reicht es nicht die Variable am Anfang zu definieren.
    Danach könntest du sie zwar in den Funktionen und Events abrufen, aber beim Ändern oder Zuweisen von Werten erzeugst du eine neue lokale Variable mit dem gleichen Namen innerhalb der Funktion, die dann auch außerhalb nicht abrufbar ist.

    D.h. um innerhalb einer Funktionen (oder in deinem Fall in Events),  eine Variable zu ändern die auch außerhalb noch verfügbar sein soll, musst du die Variable explizit mit z.B. "$script:Auswahl = 1" ansprechen.

    Abgesehen davon, hast du deinen Button Test2 zweimal definiert und somit Button "2" mit "3" überschrieben.
    Die Abfrage am Ende:

    ($auswahl -eq "Test1")

    macht so auch keinen Sinn, da du $Auswahl nur die Zahlen 1 oder 2 zuweist.


    Blog: http://www.bytecookie.de

    Powershell Code Manager: Link
    (u.a. Codesnippets verwalten + komplexe Scripte graphisch darstellen)

    Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
    Warum das Ganze? Hier gibts die Antwort.

    Samstag, 26. September 2020 12:47
    Moderator
  • $script: ist Script-Global.
    $Global ist Pprozessglobal.

    https://www.spguides.com/powershell-global-variable/

    Samstag, 26. September 2020 14:10
  • Und? :)  Welche Rolle spielt das hier?


    Blog: http://www.bytecookie.de

    Powershell Code Manager: Link
    (u.a. Codesnippets verwalten + komplexe Scripte graphisch darstellen)

    Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
    Warum das Ganze? Hier gibts die Antwort.

    Samstag, 26. September 2020 14:13
    Moderator
  • Ich geb' halt gerne zusätzliches Wissen preis.

    Daher noch ein Zusatz:
    Ist die Variable kein Objekt ist das korrekt.
    Speichere ich jedoch ein Objekt (z.B. Array, Hashtable, andere Objekte), kann ich auch ohne $global/$script die Eigenschaften ändern und die Methoden des Objektes ohne den Zugriffsmodifizierer ansprechen.

    Samstag, 26. September 2020 14:26
  • Natürlich. :)

    Blog: http://www.bytecookie.de

    Powershell Code Manager: Link
    (u.a. Codesnippets verwalten + komplexe Scripte graphisch darstellen)

    Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
    Warum das Ganze? Hier gibts die Antwort.

    Samstag, 26. September 2020 14:28
    Moderator
  • Hi, ist jetzt zwar ein bisschen spät und vielleicht hab ich auch die Frage falsch gelesen.

    Aber wenn du nur darauf aus bist einen "Tastendruck" zu speichern, kannst du einfach den KeyCode abfangen.

    $KeyCode = $_.KeyCode
    
    if($_.KeyCode -eq "1")
    {
        #Event wenn KeyCode 1
    }
    
    #Wenn du eine Form hast
        $form_Keydown = [System.Windows.Forms.KeyEventHandler]{
        $KeyCode = $_.KeyCode
    }

    Vielleicht hilft dir das

    Grüße

    Dienstag, 29. September 2020 12:48
  • Der Frager möchte nicht die Tastatur abfragen, sondern wissen, welches Control seiner Auswahl verwendet wurde.
    Das Click-Ereignis wird ausgelöst, wenn der Bediener
    a) per Maus clickt
    b) per Tab auf das Control hüpft und Enter drückt.

    Alternativ zum Speichern des Wertes könnte man auch eine ps1-Funktion mit dem Wert und/oder dem Control als Parameter aufrufen. Dann kann man auch Rückmeldungen an den User geben.
    Im Moment kann man das Ergebnis nur auswerten, wenn der Dialog beendet wird, z.B.

    $script:$Form.Hide();

    Dienstag, 29. September 2020 15:38