在WPF/Powershell中循环遍历控件 [英] Looping through controls in WPF / Powershell

查看:79
本文介绍了在WPF/Powershell中循环遍历控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图遍历Powershell/WPF应用程序中的某些控件.没什么,只是在mouseEnter事件上设置一些文本.

I am trying to loop through some controls in a Powershell / WPF application. Nothing fancy, just setting some text on a mouseEnter event.

如果我不循环代码,它将很好地工作:

It works fine if I don't loop the code:

$reader = New-Object System.Xml.XmlNodeReader $xaml 
$d = [Windows.Markup.XamlReader]::Load($reader) 

$d.FindName("GridOne").add_mouseEnter({ 
        $d.FindName("HelpText").Content = "One"
     })

$d.FindName("GridTwo").add_mouseEnter({ 
        $d.FindName("HelpText").Content = "Two"
     })

$d.FindName("GridThree").add_mouseEnter({ 
        $d.FindName("HelpText").Content = "Three"
     })

$d.FindName("GridFour").add_mouseEnter({ 
        $d.FindName("HelpText").Content = "Four"
     })     

但是,如果我尝试与循环相同的操作,它将所有控件的MouseEnter事件设置为将文本设置为数组的最后一个元素"Four":

But if I try the same thing as a loop it sets all the controls MouseEnter events to set the text to "Four", the last element of the array:

$reader = New-Object System.Xml.XmlNodeReader $xaml 
$d = [Windows.Markup.XamlReader]::Load($reader) 

$arrControls = ("One","Two","Three","Four")

foreach ($control in $arrControls) { 
     $d.FindName("Grid$control").add_mouseEnter({ 
        $d.FindName("HelpText").Content = $control
     })
}

任何人都对此有何想法,我该如何解决?

Anyone have any thoughts why this is, and how I can fix it?

谢谢

好的-这甚至更奇怪...

OK - This is even weirder...

试图按照肯特的建议使用解决方案来解决此问题.我使用$ localControl获得了相同的结果,所以以为我会尝试使用数组来确保每个条目都是不同的:

Tried to address this using a solution along the lines of Kent's suggestion. I got the same using $localControl, so thought I'd try using an array to ensure each entry was distinct:

$i = 0
$localControl = @()
foreach ($control in $arrControls) { 
    $localControl += $control
    write-host "$d.FindName('Grid$control').add_mouseEnter({ $d.FindName('HelpText').Content = $control })"
     $d.FindName("Grid$control").add_mouseEnter({ 
        $d.FindName("HelpText").Content = $localControl[$i]
        $i = $i + 1
     })
}

我知道的行为是,每当我将鼠标悬停在一个控件上时,文本就会在数组中递增一步.例如,我将鼠标悬停在第一个控件上将输出一个",下一个控件将输出"Two",依此类推,直到我的数组仅输出空值时就用尽了.

The behaviour I know get is that each time I mouseOver a control, the text just increments through the array one step. For example, the first control I hover over will output "One", the next will output "Two" and so on, until my array is exhausted when it just outputs null.

无论我将鼠标悬停在控件上的顺序如何,此一个",两个",三个",四个"的输出顺序都是相同的.

This "One", "Two", "Three", "Four" output order is the same regardless of the order I hover over the controls.

...请稍等.将$ i = $ i +1放入MouseEnter!

... Wait a minute. Have put the $i = $i + 1 in the MouseEnter!

修改为:

$i = 0
$localControl = @()
foreach ($control in $arrControls) { 
    $localControl += $control
    write-host "$d.FindName('Grid$control').add_mouseEnter({ $d.FindName('HelpText').Content = $control })"
     $d.FindName("Grid$control").add_mouseEnter({ 
        $d.FindName("HelpText").Content = $localControl[$i]
     })
     $i = $i + 1
}

将所有输出设置为null.

Sets all the outputs to null.

推荐答案

您需要关闭脚本块.您面对的是这样的:

You need to make a closure from the scriptblocks. What you are facing to is like this:

$i = 1
$block1 = { write-host $i }
$i = 2
$block2 = { write-host $i }
& $block1
& $block2

#---------------- after a change...

$i = 1
$block1 = { write-host $i }.GetNewClosure()
$i = 2
$block2 = { write-host $i }.GetNewClosure()
$i = 3
$block3 = { write-host $i }.GetNewClosure()
& $block1
& $block2
& $block3

因此,如果您进行关闭操作,可能会有所帮助:

So if you make a closure, it could help:

foreach ($control in $arrControls) { 
     $d.FindName("Grid$control").add_mouseEnter({ 
        $d.FindName("HelpText").Content = $control
     }.GetNewClosure())
}

脚本块中的变量未绑定到创建该变量的作用域.而是在当前范围内对它们进行评估:

Variables in scriptblock are not bound to the scope where there were created. Instead they are evaluated in current scope:

PS> $var = 'at beginning'
PS> $writer = { write-host $var }
PS> function test {
  $var = 1
  & $writer
  & { 
    $var = 10
    & $writer 
  }
}
PS> test
1
10
PS> & $writer
at beginning

这篇关于在WPF/Powershell中循环遍历控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆