Question
Gui-configuration dynamique de boutons
- crystof
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
Réduire
Plus d'informations
- Messages : 11
- Remerciements reçus 0
il y a 16 ans 6 mois #5227
par crystof
Gui-configuration dynamique de boutons a été créé par crystof
Bonjour à tous et merci pour ce forum.
Je voudrais me construire une interface-gui avec des boutons qui puissent êtres configurés dynamiquement via un xml.
Mais Voila mon soucis, j'arrive parfaitement à créer des boutons, ce n'est pas compliqué, mais je ne parviens pas à leurs associer une action - handler.
j'obtiens une erreur
\"Cast non valide de 'System.String' en 'System.EventHandler'\"
Si vous avez une idée ou quelques pistes ... Merci d'avance.
voici mon code
1- le xml (simplissime
)
[code:1]
<TheGui>
<Button name=\"QUIT\" action=\"$TheEnd\"/>
</TheGui>
[/code:1]
1- le ps (pareil
)
[code:1]
Param ([switch]$debug)
if ($debug) {$debugPreference=\"Continue\"}
Write-Debug \"Starting script in debug mode\"
Set-PSDebug -strict
[reflection.assembly]::loadwithpartialname(\"System.Windows.Forms\"«») | Out-Null
[reflection.assembly]::loadwithpartialname(\"System.Drawing\"«») | Out-Null
$global:Buttons=@{} #Hashtable, Button name/action association
#=== Func : Read xml config file
function ReadConfig {
$txtPath=\".\Gui.xml\"
if( ($txtPath -ne \"\"«») -and ($txtPath -notlike \"[ ]*\"«») ){ #-and (Test-Path $txtPath) ){
$global:MObj = [xml](Get-Content $txtPath)
# read xml
$global:MObj.TheGui.Button | ForEach-Object {
$global:Buttons[$_.name]+=@($_.action)
}
}else{
write-debug \"file not found\"
}
}
#=== HANDLERS
$TheEnd=
{
$form1.close()
}
#=== FORMS
$form1 = New-Object System.Windows.Forms.Form
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 121
$System_Drawing_Size.Height = 306
$form1.ClientSize = $System_Drawing_Size
$panel = New-Object System.Windows.Forms.Panel
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 93
$System_Drawing_Size.Height = 262
$panel.Size = $System_Drawing_Size
$panel.TabIndex = 23
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 12
$System_Drawing_Point.Y = 12
$panel.Location = $System_Drawing_Point
$form1.Controls.Add($panel)
#=== Process xml config
ReadConfig
$btns = new-object System.Collections.ArrayList
if ($buttons -ne $null) {
$btnOffset = 0
foreach ($action in $buttons.GetEnumerator()) {
$btn = New-Object windows.forms.Button
$btn.Text = $action.key
$btn.top = $btnOffset
$btn.Width = 60
$exprString = '$action.value'
$scriptBlock = Invoke-Expression $exprString
$btn.add_Click($($scriptBlock))
$panel.Controls.Add($btn)
$btnOffset += 30
$btns += $btn
Write-Debug \"=Add btn $($btn.Text);$($exprString);\"
}
}
#=== DISPLAY
$form1.ShowDialog()| Out-Null
[/code:1]<br><br>Message édité par: crysto444, à: 31/08/09 16:38
Je voudrais me construire une interface-gui avec des boutons qui puissent êtres configurés dynamiquement via un xml.
Mais Voila mon soucis, j'arrive parfaitement à créer des boutons, ce n'est pas compliqué, mais je ne parviens pas à leurs associer une action - handler.
j'obtiens une erreur
\"Cast non valide de 'System.String' en 'System.EventHandler'\"
Si vous avez une idée ou quelques pistes ... Merci d'avance.
voici mon code
1- le xml (simplissime
[code:1]
<TheGui>
<Button name=\"QUIT\" action=\"$TheEnd\"/>
</TheGui>
[/code:1]
1- le ps (pareil
[code:1]
Param ([switch]$debug)
if ($debug) {$debugPreference=\"Continue\"}
Write-Debug \"Starting script in debug mode\"
Set-PSDebug -strict
[reflection.assembly]::loadwithpartialname(\"System.Windows.Forms\"«») | Out-Null
[reflection.assembly]::loadwithpartialname(\"System.Drawing\"«») | Out-Null
$global:Buttons=@{} #Hashtable, Button name/action association
#=== Func : Read xml config file
function ReadConfig {
$txtPath=\".\Gui.xml\"
if( ($txtPath -ne \"\"«») -and ($txtPath -notlike \"[ ]*\"«») ){ #-and (Test-Path $txtPath) ){
$global:MObj = [xml](Get-Content $txtPath)
# read xml
$global:MObj.TheGui.Button | ForEach-Object {
$global:Buttons[$_.name]+=@($_.action)
}
}else{
write-debug \"file not found\"
}
}
#=== HANDLERS
$TheEnd=
{
$form1.close()
}
#=== FORMS
$form1 = New-Object System.Windows.Forms.Form
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 121
$System_Drawing_Size.Height = 306
$form1.ClientSize = $System_Drawing_Size
$panel = New-Object System.Windows.Forms.Panel
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 93
$System_Drawing_Size.Height = 262
$panel.Size = $System_Drawing_Size
$panel.TabIndex = 23
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 12
$System_Drawing_Point.Y = 12
$panel.Location = $System_Drawing_Point
$form1.Controls.Add($panel)
#=== Process xml config
ReadConfig
$btns = new-object System.Collections.ArrayList
if ($buttons -ne $null) {
$btnOffset = 0
foreach ($action in $buttons.GetEnumerator()) {
$btn = New-Object windows.forms.Button
$btn.Text = $action.key
$btn.top = $btnOffset
$btn.Width = 60
$exprString = '$action.value'
$scriptBlock = Invoke-Expression $exprString
$btn.add_Click($($scriptBlock))
$panel.Controls.Add($btn)
$btnOffset += 30
$btns += $btn
Write-Debug \"=Add btn $($btn.Text);$($exprString);\"
}
}
#=== DISPLAY
$form1.ShowDialog()| Out-Null
[/code:1]<br><br>Message édité par: crysto444, à: 31/08/09 16:38
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
Réduire
Plus d'informations
- Messages : 6311
- Remerciements reçus 68
il y a 16 ans 6 mois #5230
par Laurent Dardenne
Tutoriels PowerShell
Réponse de Laurent Dardenne sur le sujet Re:Gui-configuration dynamique de boutons
Salut,
tu dois créer un scriptblock :
[code:1]
$code=\"get-process\"
$sbBouton=$ExecutionContext.InvokeCommand.NewScriptBlock($code)
[/code:1]
ou en plus explicite :
[code:1]
#On cast un scriptblock en un délégué EventHandler(sender,args)
[System.EventHandler] $EventHandlerBtn = $ExecutionContext.InvokeCommand.NewScriptBlock($code)
[/code:1]
Invoke-expression retourne un PSobjet, je crois.
Si dans ton XML tu veux une indirection, utiliser le contenu du champs comme un nom de variable:
[code:1]
$FormName=\"FrmMain\"
$code='$FormName.Bouton'
$sb= $ExecutionContext.InvokeCommand.NewScriptBlock(
$ExecutionContext.InvokeCommand.ExpandString($Code)
)
$sb
[/code:1]
Enfin sache que la ligne suivante
[code:1]
$global:Buttons[$_.name]+=@($_.action)
[/code:1]
crée un nouveau tableau à chaque itération, si tu veux qq chose d'un peu plus rapide utilise une arraylist. Enfin c'est un détail
<br><br>Message édité par: Laurent Dardenne, à: 31/08/09 17:27
tu dois créer un scriptblock :
[code:1]
$code=\"get-process\"
$sbBouton=$ExecutionContext.InvokeCommand.NewScriptBlock($code)
[/code:1]
ou en plus explicite :
[code:1]
#On cast un scriptblock en un délégué EventHandler(sender,args)
[System.EventHandler] $EventHandlerBtn = $ExecutionContext.InvokeCommand.NewScriptBlock($code)
[/code:1]
Invoke-expression retourne un PSobjet, je crois.
Si dans ton XML tu veux une indirection, utiliser le contenu du champs comme un nom de variable:
[code:1]
$FormName=\"FrmMain\"
$code='$FormName.Bouton'
$sb= $ExecutionContext.InvokeCommand.NewScriptBlock(
$ExecutionContext.InvokeCommand.ExpandString($Code)
)
$sb
[/code:1]
Enfin sache que la ligne suivante
[code:1]
$global:Buttons[$_.name]+=@($_.action)
[/code:1]
crée un nouveau tableau à chaque itération, si tu veux qq chose d'un peu plus rapide utilise une arraylist. Enfin c'est un détail
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- crystof
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
Réduire
Plus d'informations
- Messages : 11
- Remerciements reçus 0
il y a 16 ans 6 mois #5232
par crystof
Réponse de crystof sur le sujet Re:Gui-configuration dynamique de boutons
je vais tester ça
Merci beaucoup.
Merci beaucoup.
Connexion ou Créer un compte pour participer à la conversation.
- crystof
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
Réduire
Plus d'informations
- Messages : 11
- Remerciements reçus 0
il y a 16 ans 6 mois #5241
par crystof
Réponse de crystof sur le sujet Re:Gui-configuration dynamique de boutons
Bonjour
Ci dessous le code modifié (si ça peut aider...)merci à Laurent pour ses conseils.
[code:1]
Param ([switch]$debug)
if ($debug) {$debugPreference=\"Continue\"}
Write-Debug \"Starting script in debug mode\"
Set-PSDebug -strict
[reflection.assembly]::loadwithpartialname(\"System.Windows.Forms\"«») | Out-Null
[reflection.assembly]::loadwithpartialname(\"System.Drawing\"«») | Out-Null
$global:Buttons=@{} #Hashtable, Button name/action association
#=== Func : Read xml config file
function ReadConfig {
$txtPath=\".\Gui.xml\"
if( ($txtPath -ne \"\"«») -and ($txtPath -notlike \"[ ]*\"«») ){ #-and (Test-Path $txtPath) ){
$global:MObj = [xml](Get-Content $txtPath)
# read xml
$global:MObj.TheGui.Button | ForEach-Object {
$global:Buttons.($_.name)+=@($_.action)
}
}else{
write-debug \"file not found\"
}
}
#=== Func :
function OnClickHandler{
$Name=($This -as [string]).split(\":\"«») -replace \" \",\"\"
$Action=$Buttons.($Name[1])
Write-host \"OnClickHandler: Clic on [$($Name[1])] button, call:$($Action);\"
& ( $ExecutionContext.InvokeCommand.NewScriptBlock($ExecutionContext.InvokeCommand.ExpandString($Action)) )
Write-debug \"OnClickHandler: End Call:$($Action);\"
}
#=== HANDLERS
$TheEnd=
{
Write-debug \"CLOSING\"
$form1.close()
}
#=== FORMS
$form1 = New-Object System.Windows.Forms.Form
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 121
$System_Drawing_Size.Height = 306
$form1.ClientSize = $System_Drawing_Size
$panel = New-Object System.Windows.Forms.Panel
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 93
$System_Drawing_Size.Height = 262
$panel.Size = $System_Drawing_Size
$panel.TabIndex = 23
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 12
$System_Drawing_Point.Y = 12
$panel.Location = $System_Drawing_Point
$form1.Controls.Add($panel)
#=== Process xml config
ReadConfig
if ($buttons -ne $null) {
$btnOffset = 0
foreach ($action in $buttons.GetEnumerator()) {
$btn = New-Object windows.forms.Button
$btn.Text = $action.key
$btn.top = $btnOffset
$btn.Width = 60
$btn.Add_Click( $ExecutionContext.InvokeCommand.NewScriptBlock( \"OnClickHandler\" ) )
Write-Debug \"=Add btn $($btn.Text);$($action.value);\"
$panel.Controls.Add($btn)
$btnOffset += 30
}
}
#=== DISPLAY
$form1.ShowDialog()| Out-Null
[/code:1]
et le xml (Gui.xml) :
[code:1]
<TheGui>
<Button name=\"QUIT\" action=\"$TheEnd\"/>
<Button name=\"testcall\" action=\".\testcall.ps1\"/>
</TheGui>
[/code:1]
La fonction OnClickHandler - ligne 1 ne me satifait pas vraiment, mais ça marche...
A+
Ci dessous le code modifié (si ça peut aider...)merci à Laurent pour ses conseils.
[code:1]
Param ([switch]$debug)
if ($debug) {$debugPreference=\"Continue\"}
Write-Debug \"Starting script in debug mode\"
Set-PSDebug -strict
[reflection.assembly]::loadwithpartialname(\"System.Windows.Forms\"«») | Out-Null
[reflection.assembly]::loadwithpartialname(\"System.Drawing\"«») | Out-Null
$global:Buttons=@{} #Hashtable, Button name/action association
#=== Func : Read xml config file
function ReadConfig {
$txtPath=\".\Gui.xml\"
if( ($txtPath -ne \"\"«») -and ($txtPath -notlike \"[ ]*\"«») ){ #-and (Test-Path $txtPath) ){
$global:MObj = [xml](Get-Content $txtPath)
# read xml
$global:MObj.TheGui.Button | ForEach-Object {
$global:Buttons.($_.name)+=@($_.action)
}
}else{
write-debug \"file not found\"
}
}
#=== Func :
function OnClickHandler{
$Name=($This -as [string]).split(\":\"«») -replace \" \",\"\"
$Action=$Buttons.($Name[1])
Write-host \"OnClickHandler: Clic on [$($Name[1])] button, call:$($Action);\"
& ( $ExecutionContext.InvokeCommand.NewScriptBlock($ExecutionContext.InvokeCommand.ExpandString($Action)) )
Write-debug \"OnClickHandler: End Call:$($Action);\"
}
#=== HANDLERS
$TheEnd=
{
Write-debug \"CLOSING\"
$form1.close()
}
#=== FORMS
$form1 = New-Object System.Windows.Forms.Form
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 121
$System_Drawing_Size.Height = 306
$form1.ClientSize = $System_Drawing_Size
$panel = New-Object System.Windows.Forms.Panel
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 93
$System_Drawing_Size.Height = 262
$panel.Size = $System_Drawing_Size
$panel.TabIndex = 23
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 12
$System_Drawing_Point.Y = 12
$panel.Location = $System_Drawing_Point
$form1.Controls.Add($panel)
#=== Process xml config
ReadConfig
if ($buttons -ne $null) {
$btnOffset = 0
foreach ($action in $buttons.GetEnumerator()) {
$btn = New-Object windows.forms.Button
$btn.Text = $action.key
$btn.top = $btnOffset
$btn.Width = 60
$btn.Add_Click( $ExecutionContext.InvokeCommand.NewScriptBlock( \"OnClickHandler\" ) )
Write-Debug \"=Add btn $($btn.Text);$($action.value);\"
$panel.Controls.Add($btn)
$btnOffset += 30
}
}
#=== DISPLAY
$form1.ShowDialog()| Out-Null
[/code:1]
et le xml (Gui.xml) :
[code:1]
<TheGui>
<Button name=\"QUIT\" action=\"$TheEnd\"/>
<Button name=\"testcall\" action=\".\testcall.ps1\"/>
</TheGui>
[/code:1]
La fonction OnClickHandler - ligne 1 ne me satifait pas vraiment, mais ça marche...
A+
Connexion ou Créer un compte pour participer à la conversation.
- crystof
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
Réduire
Plus d'informations
- Messages : 11
- Remerciements reçus 0
il y a 16 ans 6 mois #5243
par crystof
Réponse de crystof sur le sujet Re:Gui-configuration dynamique de boutons
Bonjour
Ci dessous le code modifié (si ça peut aider...)merci à Laurent pour ses conseils.
[code:1]
Param ([switch]$debug)
if ($debug) {$debugPreference=\"Continue\"}
Write-Debug \"Starting script in debug mode\"
Set-PSDebug -strict
[reflection.assembly]::loadwithpartialname(\"System.Windows.Forms\"«») | Out-Null
[reflection.assembly]::loadwithpartialname(\"System.Drawing\"«») | Out-Null
$global:Buttons=@{} #Hashtable, Button name/action association
#=== Func : Read xml config file
function ReadConfig {
$txtPath=\".\Gui.xml\"
if( ($txtPath -ne \"\"«») -and ($txtPath -notlike \"[ ]*\"«») ){ #-and (Test-Path $txtPath) ){
$global:MObj = [xml](Get-Content $txtPath)
# read xml
$global:MObj.TheGui.Button | ForEach-Object {
$global:Buttons.($_.name)+=@($_.action)
}
}else{
write-debug \"file not found\"
}
}
#=== Func :
function OnClickHandler{
$Name=($This -as [string]).split(\":\"«») -replace \" \",\"\"
$Action=$Buttons.($Name[1])
Write-host \"OnClickHandler: Clic on [$($Name[1])] button, call:$($Action);\"
& ( $ExecutionContext.InvokeCommand.NewScriptBlock($ExecutionContext.InvokeCommand.ExpandString($Action)) )
Write-debug \"OnClickHandler: End Call:$($Action);\"
}
#=== HANDLERS
$TheEnd=
{
Write-debug \"CLOSING\"
$form1.close()
}
#=== FORMS
$form1 = New-Object System.Windows.Forms.Form
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 121
$System_Drawing_Size.Height = 306
$form1.ClientSize = $System_Drawing_Size
$panel = New-Object System.Windows.Forms.Panel
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 93
$System_Drawing_Size.Height = 262
$panel.Size = $System_Drawing_Size
$panel.TabIndex = 23
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 12
$System_Drawing_Point.Y = 12
$panel.Location = $System_Drawing_Point
$form1.Controls.Add($panel)
#=== Process xml config
ReadConfig
if ($buttons -ne $null) {
$btnOffset = 0
foreach ($action in $buttons.GetEnumerator()) {
$btn = New-Object windows.forms.Button
$btn.Text = $action.key
$btn.top = $btnOffset
$btn.Width = 60
$btn.Add_Click( $ExecutionContext.InvokeCommand.NewScriptBlock( \"OnClickHandler\" ) )
Write-Debug \"=Add btn $($btn.Text);$($action.value);\"
$panel.Controls.Add($btn)
$btnOffset += 30
}
}
#=== DISPLAY
$form1.ShowDialog()| Out-Null
[/code:1]
et le xml (Gui.xml) :
[code:1]
<TheGui>
<Button name=\"QUIT\" action=\"$TheEnd\"/>
<Button name=\"testcall\" action=\".\testcall.ps1\"/>
</TheGui>
[/code:1]
La fonction OnClickHandler - ligne 1 ne me satifait pas vraiment, mais ça marche...
A+
Ci dessous le code modifié (si ça peut aider...)merci à Laurent pour ses conseils.
[code:1]
Param ([switch]$debug)
if ($debug) {$debugPreference=\"Continue\"}
Write-Debug \"Starting script in debug mode\"
Set-PSDebug -strict
[reflection.assembly]::loadwithpartialname(\"System.Windows.Forms\"«») | Out-Null
[reflection.assembly]::loadwithpartialname(\"System.Drawing\"«») | Out-Null
$global:Buttons=@{} #Hashtable, Button name/action association
#=== Func : Read xml config file
function ReadConfig {
$txtPath=\".\Gui.xml\"
if( ($txtPath -ne \"\"«») -and ($txtPath -notlike \"[ ]*\"«») ){ #-and (Test-Path $txtPath) ){
$global:MObj = [xml](Get-Content $txtPath)
# read xml
$global:MObj.TheGui.Button | ForEach-Object {
$global:Buttons.($_.name)+=@($_.action)
}
}else{
write-debug \"file not found\"
}
}
#=== Func :
function OnClickHandler{
$Name=($This -as [string]).split(\":\"«») -replace \" \",\"\"
$Action=$Buttons.($Name[1])
Write-host \"OnClickHandler: Clic on [$($Name[1])] button, call:$($Action);\"
& ( $ExecutionContext.InvokeCommand.NewScriptBlock($ExecutionContext.InvokeCommand.ExpandString($Action)) )
Write-debug \"OnClickHandler: End Call:$($Action);\"
}
#=== HANDLERS
$TheEnd=
{
Write-debug \"CLOSING\"
$form1.close()
}
#=== FORMS
$form1 = New-Object System.Windows.Forms.Form
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 121
$System_Drawing_Size.Height = 306
$form1.ClientSize = $System_Drawing_Size
$panel = New-Object System.Windows.Forms.Panel
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 93
$System_Drawing_Size.Height = 262
$panel.Size = $System_Drawing_Size
$panel.TabIndex = 23
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 12
$System_Drawing_Point.Y = 12
$panel.Location = $System_Drawing_Point
$form1.Controls.Add($panel)
#=== Process xml config
ReadConfig
if ($buttons -ne $null) {
$btnOffset = 0
foreach ($action in $buttons.GetEnumerator()) {
$btn = New-Object windows.forms.Button
$btn.Text = $action.key
$btn.top = $btnOffset
$btn.Width = 60
$btn.Add_Click( $ExecutionContext.InvokeCommand.NewScriptBlock( \"OnClickHandler\" ) )
Write-Debug \"=Add btn $($btn.Text);$($action.value);\"
$panel.Controls.Add($btn)
$btnOffset += 30
}
}
#=== DISPLAY
$form1.ShowDialog()| Out-Null
[/code:1]
et le xml (Gui.xml) :
[code:1]
<TheGui>
<Button name=\"QUIT\" action=\"$TheEnd\"/>
<Button name=\"testcall\" action=\".\testcall.ps1\"/>
</TheGui>
[/code:1]
La fonction OnClickHandler - ligne 1 ne me satifait pas vraiment, mais ça marche...
A+
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
Réduire
Plus d'informations
- Messages : 6311
- Remerciements reçus 68
il y a 16 ans 6 mois #5244
par Laurent Dardenne
Tutoriels PowerShell
Réponse de Laurent Dardenne sur le sujet Re:Gui-configuration dynamique de boutons
Salut,
crysto444 écrit:
Il manque tout de même de commentaires, pour que chacun puisse le comprendre.
De mon coté je pense que le mieux serait d'ajouter, un nom au composant, comme ceci :
[code:1]
$BtnNumber=0
foreach ($action in $buttons.GetEnumerator()) {
$btn = New-Object windows.forms.Button
$btn.Text = $action.key
$btn.top = $btnOffset
$btn.Width = 60
$btn.Name=\"Bouton$($BtnNumber++;$btnnumber)\"
[/code:1]
Du coup, je suppose que pour toi l'idée est que le nom du bouton est égal au texte affiché.
Si c'est le cas on ne peux plus modifier le texte, car ce texte est référencé dans le tableau $Buttons, faut le savoir.
Peut-être manque-t-il un champ XML pour le nom du bouton ?
crysto444 écrit:
Tu peux simplifier comme ceci :
[code:1]
function OnClickHandler{
#$this = sender
$Name=$this.Text
$Action=$Buttons.($Name)
Write-host \"OnClickHandler: Clic on [$Name] button, call:$($Action[0]);\"
& ( $ExecutionContext.InvokeCommand.NewScriptBlock($ExecutionContext.InvokeCommand.ExpandString($Action[0])) )
Write-debug \"OnClickHandler: End Call:$($Action[0]);\"
}
[/code:1]
Une chose aussi à comprendre est qu'il n'y a qu'un seul gestionnaire d'événement pour tous les boutons.
Dans ce cas tu peux simplifier l'appel, c'est tjr le même :
[code:1]
$btn.Add_Click( {OnClickHandler} )
[/code:1]
A mon avis, il n'est pas nécessaire d'utiliser le dynamisme ici (pour le moment ?).
Que tu permettes plusieurs occurences d'un nom de bouton dans le XML, fait que le tableau d'action est bien expansé mais cela ne peut être qu'une seule instruction.
C'est à dire que si le tableau contient + instructions indépendante, tu dois les séparer par un point virgule ou un retour chariot.
Ensuite si le contenu de ton action est toujours un nom de scriptblock déclaré dans le script de la form, il existe donc forcément au travers d'une variable, celle que tu indiques dans le XML, tu peux faire ceci :
[code:1]
#récupère le nom d'une variable puis la variable et enfin son contenu : le code
(gv $name.Remove(0,1)).value
#Ou son exécution
&((gv $name.Remove(0,1)).value)
[/code:1]
Mais si on procéde ainsi le reste ne fonctionne plus, on doit savoir quand le faire ou ne pas le faire.
Sinon, comme tu dois le savoir, ceci permet de ne pas expanser la chaîne :
[code:1]action=\"Dir `$pwd\"[/code:1]
sans cela on écrit en dur le nom du répertoire
[code:1]'Dir c:\'[/code:1]
Il manque peut être un peu plus de paramètrage dans le XML, par exemple on ne peut pas insérer + lignes dans un attribut.
Une autre approche :
[code:1]
<TheGui>
<Button>
<name>QUIT</name>
<action>$TheEnd</action>
</Button>
<Button>
<name>testcall</name>
<action>.\testcall.ps1</action>
</Button>
<Button>
<name>Arrête la surveillance des process notepad</name>
<action><![CDATA[# Event WMi via .NET
$Event=New-object WMIEvent.PoshStopWatchingEvent(\"Process\",
$pid,
([System.Management.Automation.Runspaces.Runspace]::«»DefaultRunSpace).InstanceID,
[WMIEvent.PoshTransmissionActor]::«»PowerShell)
#déclenche l'événement WMI
$Event.Fire()
]]></action>
</Button>
</TheGui>
<!-- lecture cdata :$XML.TheGui.Button[2].action.get_innerxml()-->
[/code:1]
Mais ici ce n'est peut être pas ton besoin, mais le mien
A ce sujet, quel était l'objectif initial ?
crysto444 écrit:
Oui, il est trés bien ton script.si ça peut aider...
Il manque tout de même de commentaires, pour que chacun puisse le comprendre.
De mon coté je pense que le mieux serait d'ajouter, un nom au composant, comme ceci :
[code:1]
$BtnNumber=0
foreach ($action in $buttons.GetEnumerator()) {
$btn = New-Object windows.forms.Button
$btn.Text = $action.key
$btn.top = $btnOffset
$btn.Width = 60
$btn.Name=\"Bouton$($BtnNumber++;$btnnumber)\"
[/code:1]
Du coup, je suppose que pour toi l'idée est que le nom du bouton est égal au texte affiché.
Si c'est le cas on ne peux plus modifier le texte, car ce texte est référencé dans le tableau $Buttons, faut le savoir.
Peut-être manque-t-il un champ XML pour le nom du bouton ?
crysto444 écrit:
A première vue je n'ai pas compris ce que c'était sensé faireLa fonction OnClickHandler - ligne 1 ne me satifait pas vraiment, mais ça marche...
Tu peux simplifier comme ceci :
[code:1]
function OnClickHandler{
#$this = sender
$Name=$this.Text
$Action=$Buttons.($Name)
Write-host \"OnClickHandler: Clic on [$Name] button, call:$($Action[0]);\"
& ( $ExecutionContext.InvokeCommand.NewScriptBlock($ExecutionContext.InvokeCommand.ExpandString($Action[0])) )
Write-debug \"OnClickHandler: End Call:$($Action[0]);\"
}
[/code:1]
Une chose aussi à comprendre est qu'il n'y a qu'un seul gestionnaire d'événement pour tous les boutons.
Dans ce cas tu peux simplifier l'appel, c'est tjr le même :
[code:1]
$btn.Add_Click( {OnClickHandler} )
[/code:1]
A mon avis, il n'est pas nécessaire d'utiliser le dynamisme ici (pour le moment ?).
Que tu permettes plusieurs occurences d'un nom de bouton dans le XML, fait que le tableau d'action est bien expansé mais cela ne peut être qu'une seule instruction.
C'est à dire que si le tableau contient + instructions indépendante, tu dois les séparer par un point virgule ou un retour chariot.
Ensuite si le contenu de ton action est toujours un nom de scriptblock déclaré dans le script de la form, il existe donc forcément au travers d'une variable, celle que tu indiques dans le XML, tu peux faire ceci :
[code:1]
#récupère le nom d'une variable puis la variable et enfin son contenu : le code
(gv $name.Remove(0,1)).value
#Ou son exécution
&((gv $name.Remove(0,1)).value)
[/code:1]
Mais si on procéde ainsi le reste ne fonctionne plus, on doit savoir quand le faire ou ne pas le faire.
Sinon, comme tu dois le savoir, ceci permet de ne pas expanser la chaîne :
[code:1]action=\"Dir `$pwd\"[/code:1]
sans cela on écrit en dur le nom du répertoire
[code:1]'Dir c:\'[/code:1]
Il manque peut être un peu plus de paramètrage dans le XML, par exemple on ne peut pas insérer + lignes dans un attribut.
Une autre approche :
[code:1]
<TheGui>
<Button>
<name>QUIT</name>
<action>$TheEnd</action>
</Button>
<Button>
<name>testcall</name>
<action>.\testcall.ps1</action>
</Button>
<Button>
<name>Arrête la surveillance des process notepad</name>
<action><![CDATA[# Event WMi via .NET
$Event=New-object WMIEvent.PoshStopWatchingEvent(\"Process\",
$pid,
([System.Management.Automation.Runspaces.Runspace]::«»DefaultRunSpace).InstanceID,
[WMIEvent.PoshTransmissionActor]::«»PowerShell)
#déclenche l'événement WMI
$Event.Fire()
]]></action>
</Button>
</TheGui>
<!-- lecture cdata :$XML.TheGui.Button[2].action.get_innerxml()-->
[/code:1]
Mais ici ce n'est peut être pas ton besoin, mais le mien
A ce sujet, quel était l'objectif initial ?
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
Temps de génération de la page : 0.068 secondes
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Entraide pour les débutants
- Gui-configuration dynamique de boutons