在powershell中动态生成/连接WPF表项



不知道如何最好地表达这个问题,但我如何动态地生成所有这些元素,并为生成的元素分配一个add_click ?

我在powershell中使用foreach循环来基于powershell对象的内容构建一个选项卡式WPF窗口。

在将控件添加到选项卡按钮以允许它显示选项卡之前,一切都正常工作。我认为这是因为在foreach中,我为每个元素使用了相同的变量名,而且我不确定如何指定将哪个表项分配给每个表按钮。

另外,我正在寻找一个只有powershell的解决方案。

我认为我可能能够使用New-Variable/Get-Variable来构建变量名称中包含计数器的变量,但add_click仍然无法调用表项。


添加2023年1月20日

Add-Type -AssemblyName PresentationCore, PresentationFramework, System.Windows.Forms, System.Drawing
#Region XAML for base gui
$Xaml = @"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="1000"
Height="700"
Margin="0,0,0,0"
Background="#35333a"
BorderBrush="#666374"
Foreground="#514e5d"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
AllowsTransparency="True"
ResizeMode="CanResize">
<Grid Background="#241b2f" Name="MainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="3*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="6*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="6" VerticalAlignment="Center" HorizontalAlignment="Center" Height="20" Width="20" Background="white" BorderThickness="0,0,0,0" Name="CloseButton" />
<ScrollViewer VerticalScrollBarVisibility="Hidden" Grid.Row="1" Grid.RowSpan="4">
<StackPanel Name="QuestionTabsPanel">
</StackPanel>
</ScrollViewer>
<TabControl Background="#241b2f" BorderThickness="0,0,0,0" Padding="-1" Grid.Row="1" Grid.Column="2" Name="TabControlPanel" SelectedIndex="0">
</TabControl>
</Grid>
</Window>
"@
#EndRegion
# get questions from json and convert them to objects
$Json = get-content 'C:Usersd.eckhout.milDesktopFilesquestions.json' | ConvertFrom-Json
$Questions = $Json | foreach{
[pscustomobject]@{
QuestionText = $_.questiontext
Image = $_.image
Answers = $_.answers
CorrectAnswer = $_.correctanswer
Explaination = $_.explaination
}
}
# counting variables
$QuestionsCorrect = 0
$QuestionNumber = 1
# randomize questions
$Questions = $Questions | Sort-Object {Get-Random}
# build window with base xaml
$Window = [Windows.Markup.XamlReader]::Parse($Xaml)
[xml]$xml = $Xaml
$xml.SelectNodes("//*[@Name]") | ForEach-Object { Set-Variable -Name $_.Name -Value $Window.FindName($_.Name) }
# custom close button event
$CloseButton.Add_Click({$Window.Close()})
# Make window moveable
$Window.Add_MouseDown({
if ($_.ChangedButton -eq 'Left'){
$this.DragMove()
}
})
# loop through our question objects and build a tab for each
foreach ($Question in $Questions){
#Region Add a tab button for the question to sidebar
$TabButton = New-Object System.Windows.Controls.Button
$TabButton.Name = "TabButton$QuestionNumber"
$TabButton.content = "$QuestionNumber"
$TabButton.Height="40"
$TabButton.Background="#241b2f"
$TabButton.BorderThickness="0,0,0,0"
$TabButton.Foreground="#ffffff"
$QuestionTabsPanel.Children.Add($TabButton)
#EndRegion
#Region Create tab content panel for the question
$TabContent = New-Object System.Windows.Controls.TabItem
#$TabContent.Visibility="Collapsed"
$TabContent.Name="TabContent$QuestionNumber"
$TabControlPanel.Items.Add($TabContent)
#EndRegion
$TabButton.Add_Click({
$sauceButton=$_ #the button this click event was triggered by
$sauceButtonContent=[Int]$sauceButton.Content #its content casted as Int
$tabIndexToSelect=$sauceButtonContent-1 # the first tabItem has index 0
$TabControlPanel.SelectedIndex = $tabIndexToSelect
})
#Region Add grid to tab content area...grid lets us better control placement of children
$TabContentStack = New-Object System.Windows.Controls.StackPanel
$TabContentStack.Name="TabStack$QuestionNumber"
$TabContent.Content = ($TabContentStack)
#EndRegion
#Region Add question text to grid
$TabContentQuestionText = New-Object System.Windows.Controls.TextBlock
$TabContentQuestionText.HorizontalAlignment="Center"
$TabContentQuestionText.VerticalAlignment="Top"
$TabContentQuestionText.TextWrapping="Wrap"
$TabContentQuestionText.Text=$Question.QuestionText
$TabContentQuestionText.FontSize="14"
$TabContentQuestionText.Height="21"
$TabContentQuestionText.Foreground="#ffffff"
$TabContentStack.Children.Add($TabContentQuestionText)
#EndRegion
$QuestionNumber++
}
$Window.ShowDialog()
[
{
"questiontext": "lorem ipsum?",
"answers": [
"first ipsum",
"second ipsum",
"third ipsum",
"fourth ipsum"
],
"correctanswer": "lorem ipsum",
"explaination": "lorem ipsum"
},
{
"questiontext": "lorem ipsum?",
"answers": [
"first ipsum",
"second ipsum",
"third ipsum",
"fourth ipsum"
],
"correctanswer": "lorem ipsum",
"explaination": "lorem ipsum"
}
]

GUI运行图片

您可以使用selecedIndex与您的点击事件的按钮的内容:

$TabButton.Add_Click({
$sauceButton=$_ #the button this click event was triggered by
$sauceButtonContent=[Int]$sauceButton.Content #its content casted as Int
$tabIndexToSelect=$sauceButtonContent-1 # the first tabItem has index 0
$TabControlPanel.SelectedIndex = $tabIndexToSelect 
})

然而,我建议创建一个数据上下文,为每个表项添加ps-objects到该上下文,并将其绑定到tabcontrol,并将属性itemsource设置为"binging"Powershell XAML -使用XAML数据模板创建新表项

最新更新