Цикл управления в WPF / Powershell - PullRequest
       10

Цикл управления в WPF / Powershell

0 голосов
/ 06 августа 2010

Я пытаюсь перебрать некоторые элементы управления в приложении Powershell / WPF. Ничего особенного, просто установив некоторый текст для события mouseEnter.

Работает нормально, если я не зацикливаю код:

$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 для элементов управления, чтобы установить для текста значение "Четыре", последний элемент массива:

$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
     })
}

У кого-нибудь есть мысли, почему это так, и как я могу это исправить?

Спасибо

Ben

ОК - Это еще более странно ...

Пытался решить эту проблему, используя решение, аналогичное предложению Кента. Я получил то же самое, используя $ localControl, поэтому подумал, что попробую использовать массив, чтобы убедиться, что каждая запись различна:

$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
     })
}

Поведение, которое я знаю, заключается в том, что каждый раз при наведении курсора мыши на элемент управления текст просто увеличивается на один шаг в массиве. Например, первый элемент управления, над которым я наведите курсор мыши, выведет «One», следующий - «Two» и т. Д., Пока мой массив не будет исчерпан, когда он просто выведет ноль.

Этот порядок вывода «Один», «Два», «Три», «Четыре» одинаков независимо от порядка наведения на элементы управления.

... Подожди минутку. Поместите $ i = $ i + 1 в 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
}

Устанавливает все выходы на ноль.

Ответы [ 2 ]

1 голос
/ 06 августа 2010

Вам нужно сделать замыкание из блоков скриптов. То, с чем вы сталкиваетесь, выглядит так:

$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

Так что, если вы сделаете закрытие, это может помочь:

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

Переменные в блоке сценария не привязаны к области, в которой они были созданы. Вместо этого они оцениваются в текущей области:

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
0 голосов
/ 06 августа 2010

Возьмите локальную копию $control:

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

Все ссылки на $control разрешаются после завершения цикла, поэтому все они ссылаются на последний элемент в вашей коллекции.

...