Форма WPF XAML, сгенерированная на лету - как ссылаться на элементы xaml позже - PullRequest
0 голосов
/ 05 марта 2019

У меня есть некоторый код powershell, где я использую шаблон xaml для генерации сетки серверов. Поскольку количество серверов и имен будет изменяться (по данным электронной таблицы), я не могу жестко закодировать имена элементов XAML.

Я могу генерировать сетку (элементы сервера, сгруппированные по типам серверов) без каких-либо проблем. моя проблема сейчас как ссылаться на элементы XAML, сгенерированные «на лету» позже. Я чувствую, что это относительно простой вопрос, основанный на сложности того, что я уже делаю, но я новичок в работе с XAML, особенно при создании формы XAML на лету.

Вот шаблон XAML и две функции, которые генерируют элементы xaml на лету.

    [xml]$xaml = @'
    <Window 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Title='MainWindow' Height='Auto' Width='Auto' FontSize='9'> 
    <Window.Resources> 
        <Style x:Key="GroupBoxStyle1" TargetType="{x:Type GroupBox}">
            <Setter Property="BorderBrush" Value="Blue"/>
            <Setter Property="BorderThickness" Value="5"/>
            <Setter Property="Template">
                <Setter.Value>
                      <ControlTemplate TargetType="GroupBox">
                        <Grid>
                          <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="*" />
                          </Grid.RowDefinitions>

                          <Border Grid.Row="0"
                                  Grid.ColumnSpan="2"
                                  BorderThickness="1"
                                  BorderBrush="#25A0DA"
                                  Background="#25A0DA">
                              <Label Foreground="White">   
                                  <ContentPresenter Margin="4"
                                              ContentSource="Header"
                                              RecognizesAccessKey="True" />
                              </Label>
                          </Border>
                          <Border Grid.Row="1"
                                  BorderThickness="1,0,1,1"
                                  BorderBrush="#25A0DA">
                            <ContentPresenter Margin="4" />
                          </Border>
                        </Grid>
                      </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <ScrollViewer ScrollViewer.VerticalScrollBarVisibility ='Auto' ScrollViewer.HorizontalScrollBarVisibility ='Auto'>
    <Grid ShowGridLines="False" Name='StartingGrid'>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>

            <Button 
                Name='Refresh_Btn' 
                Content='Refresh' 
                Width='70'
                Height='30'
                FontSize="9" 
                FontWeight="Bold" 
                Grid.Column="0" 
                Grid.Row="0"/>

            <Button 
                Name='Reboot_Btn' 
                Content='Reboot' 
                Width='70'
                Height='30'
                FontSize="9" 
                FontWeight="Bold" 
                Grid.Column="1" 
                Grid.Row="0"/>

    </Grid> 
 </ScrollViewer>
</Window>
'@

Function CreateServerGrid{
    $srv = $Srv.name
    $grd = New-Object system.windows.controls.grid
    $grd.Name = "Server" + ($counter)
    #$grd.ShowGridLines = 'True'
    $row1 = new-object system.windows.controls.rowdefinition
    $row1.height = "Auto"
    $row2 = new-object system.windows.controls.rowdefinition
    $row2.height = "Auto"
    $row3 = new-object system.windows.controls.rowdefinition
    $row3.height = "Auto"

    $col1 = new-object system.windows.controls.columndefinition
    $col1.width = "Auto"
    $col2 = new-object system.windows.controls.columndefinition
    $col2.width = "Auto"
    $col3 = new-object system.windows.controls.columndefinition
    $col3.width = "Auto"

    $grd.RowDefinitions.add($row1)
    $grd.RowDefinitions.add($row2)
    $grd.RowDefinitions.add($row3)

    $grd.ColumnDefinitions.add($col1)
    $grd.ColumnDefinitions.add($col2)
    $grd.ColumnDefinitions.add($col3)

   $ServerLabel = New-Object System.Windows.Controls.Label
   $ServerLabel.Name = "$srv"
   $ServerLabel.FontWeight = "UltraBold"
   $ServerLabel.Content = $srv
   [System.Windows.Controls.Grid]::SetRow($ServerLabel,0)
   [System.Windows.Controls.Grid]::SetColumn($ServerLabel,0)
   $ServerLabel.HorizontalAlignment = 'Right'
   #RegisterName($srv.name,$ServerLabel)
   #$GUIhash.Add($_.TargetType,$_)

   $ItemLabel0 = New-Object System.Windows.Controls.Label
   $ItemLabel0.Name = "Label_LastDeployment_$srv"
   #$ItemLabel1.Height = "Auto"
   $ItemLabel0.Content = "Last Deployment:  " 
   [System.Windows.Controls.Grid]::SetRow($ItemLabel0,1)
   [System.Windows.Controls.Grid]::SetColumn($ItemLabel0,1)

   $ItemText0 = New-Object System.Windows.Controls.textBox
   $ItemText0.Name = "LD_$srv"
   #$ItemLabel1.Height = "Auto"
   $ItemText0.text = "OtherData1 " + ($counter + 2 )
   [System.Windows.Controls.Grid]::SetRow($ItemText0,1)
   [System.Windows.Controls.Grid]::SetColumn($ItemText0,2)

   $ItemLabel1 = New-Object System.Windows.Controls.Label
   $ItemLabel1.Name = "Label_LastReboot_$srv"
   #$ItemLabel1.Height = "Auto"
   $ItemLabel1.Content = "Last Reboot:  "
   [System.Windows.Controls.Grid]::SetRow($ItemLabel1,2)
   [System.Windows.Controls.Grid]::SetColumn($ItemLabel1,1)

   $ItemText1 = New-Object System.Windows.Controls.textBox
   $ItemText1.Name = "LR_$srv"
   #$ItemLabel1.Height = "Auto"
   $ItemText1.text = "OtherData1 " + ($counter + 2 )
   [System.Windows.Controls.Grid]::SetRow($ItemText1,2)
   [System.Windows.Controls.Grid]::SetColumn($ItemText1,2)


    $grd.AddChild($ServerLabel)
    $grd.AddChild($ItemLabel0)
    $grd.AddChild($ItemText0)   
    $grd.AddChild($ItemLabel1)
    $grd.AddChild($ItemText1)   


    return $grd

}

Function StartTheFun {

    $script:counter = 1 

foreach ($grp in $grouping){ 
   $WPFStartingGrid.RowDefinitions.add((new-object System.Windows.Controls.RowDefinition -property @{ Height = 'Auto'}))

   If($Counter -eq 3){
    $script:cnt ++
    $WPFStartingGrid.ColumnDefinitions.add((new-object System.Windows.Controls.ColumnDefinition -property @{ Width = 'Auto'}))
    $script:counter = 1 
    }
   $grid =@()

   $newStkPnl = new-object System.Windows.Controls.Grid

   $NewGB = New-Object System.Windows.Controls.GroupBox
   $NewGB.Header = $grp
   $NewGB.Margin = "0"
   $init = 0
   $ct = 0
   $srvCnt = ($list | ?{$_.'Computer_Description' -match $grp}).count
   #Write-Host $grp
   #Write-Host "ServerCount:  " $srvCnt
   $CntCheck = $false
   if ($srvCnt -gt 4){$CntCheck = $true}
   #Write-Host "CntCheck:  " $CntCheck 

   foreach ($srv in $list | ?{$_.'Computer_Description' -match $grp}) {
        Write-Host 'Server:  ' $srv.name
        Write-Host 'Init:  ' $init
        $newStkPnl.RowDefinitions.add((new-object System.Windows.Controls.RowDefinition -property @{ Height = 'Auto'}))
        #$ControlObj.Add($srv.Name,$_)
        $grid = CreateServerGrid $srv
        [System.Windows.Controls.Grid]::SetRow($grid,$init)
        [System.Windows.Controls.Grid]::SetColumn($grid,$ct)
        $newStkPnl.AddChild($grid)
        $init ++
        $srvCnt --
        if($srvCnt -gt 0){
            If ($init -gt 3){
                    $newStkPnl.ColumnDefinitions.add((new-object System.Windows.Controls.ColumnDefinition -property @{ Width = 'Auto'}))
                    $ct ++
                    $init = 0
                }
            If (($srvCnt -gt 0) -and ($init -eq 0)){
                    $newStkPnl.ColumnDefinitions.add((new-object System.Windows.Controls.ColumnDefinition -property @{ Width = 'Auto'}))
                    $ct ++
                    $init = 0
                }
        }


        Write-Host 'NewSrvCnt:  ' $srvCnt
        }

   $NewGB.Content = $newStkPnl
   $NewGB.Name = 'Group' + ($counter)
   $NewGB.Style = $GuiHash.Window.FindResource("GroupBoxStyle1")
    [System.Windows.Controls.Grid]::SetRow($NewGB,$counter)
    [System.Windows.Controls.Grid]::SetColumn($NewGB,$cnt) 
   $Script:counter ++
   $WPFStartingGrid.AddChild($NewGB) 
   }


    }

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

enter image description here

...