wpf 我想使用一个循环来创建基于PowerShell中XML窗口的所有命名方面的变量

1bqhqjot  于 2023-10-22  发布在  Shell
关注(0)|答案(2)|浏览(95)

请注意,我并不是一个有经验的程序员,我要去大学的IT和什么我没有在课堂上学习,我从谷歌和StackOverflow刮
我正在使用GUI创建一个PowerShell脚本,这既是一个挑战/练习,也是一个工具,可以帮助我完成兼职IT映像工作。我已经完成了所有内容的XML部分,现在我正在处理实际的逻辑,以给予窗口功能。
其中一部分是将所有命名的文本框/单选按钮分配给PowerShell中的变量,如果你像这样硬编码变量分配,这并不难:$radioButton = $window.FindName("radioButton")
然而,我有相当数量的文本框/单选按钮,我想操作,虽然我可以坐下来硬编码所有这些(我可能应该,因为这些都不会改变),我想做一个循环,遍历窗口中命名的所有内容,并基于它创建一个变量,主要是为了挑战,学习,因为它看起来更干净。
可能需要注意的是,我没有导入.xaml文件,它存在于PS脚本中,因此它不需要指向.xaml文件。
整个脚本本身,现在还没有完成,因为我试图创建的循环不起作用,这意味着变量没有被赋值:

Add-Type -AssemblyName PresentationFramework

[xml]$xaml = @"
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ImagingInfoSample"
        Title="Imaging Ticket Creator" Height="500" Width="500">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="b2v" />
    </Window.Resources>
    <Grid>
        <TabControl>
            <TabItem Header="Ticket Information">
                <Grid Background="#FFE5E5E5">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="101*"/>
                        <ColumnDefinition Width="23*"/>
                        <ColumnDefinition Width="320*"/>
                    </Grid.ColumnDefinitions>
                    <StackPanel Margin="11" Width="300" Grid.ColumnSpan="3" HorizontalAlignment="Left">
                        <StackPanel.Resources>
                            <Style TargetType="{x:Type RadioButton}">
                                <Setter Property="Margin" Value="0,10,0,0"/>
                            </Style>
                        </StackPanel.Resources>
                        <Label FontWeight="Bold" Content="Imaging or Reimaging?"></Label>
                        <RadioButton x:Name="imgBtn" GroupName="jobType">Imaging</RadioButton>
                        <RadioButton x:Name ="reimgBtn" GroupName="jobType">Reimaging</RadioButton>
                        <Label FontWeight="Bold" Content="Make:" ></Label>
                        <Label FontWeight="Bold" Content="Model:"></Label>
                        <Label FontWeight="Bold" Content="Tag Type/Number:"></Label>
                        <RadioButton x:Name="blkTag" GroupName="tagType">Black Tag</RadioButton>
                        <RadioButton x:Name="whtTag" GroupName="tagType">White Tag</RadioButton>
                        <RadioButton x:Name="bthTag" GroupName="tagType">Both (Fill in both boxes above if selecting this)</RadioButton>
                        <Label FontWeight="Bold" Content="Serial Number:"></Label>
                        <Label FontWeight="Bold" Content="Laptop or Desktop?"></Label>
                        <RadioButton x:Name="lapTop" GroupName="lapOrDesk">Laptop</RadioButton>
                        <RadioButton x:Name="deskTop" GroupName="lapOrDesk">Desktop</RadioButton>
                    </StackPanel>
                    <TextBox x:Name="compMake" Grid.Column="1" HorizontalAlignment="Left" Margin="0,92,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Grid.ColumnSpan="2"/>
                    <TextBox x:Name="compModel" Grid.Column="1" HorizontalAlignment="Left" Margin="0,115,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Grid.ColumnSpan="2"/>
                    <TextBox x:Name="blackTagBox" HorizontalAlignment="Left" Margin="0,176,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Grid.ColumnSpan="2" Grid.Column="1"/>
                    <TextBox x:Name="whiteTagBox" Grid.Column="1" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Grid.ColumnSpan="2" Margin="0,199,0,0"/>
                    <TextBox x:Name="snBox" Grid.Column="1" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Grid.ColumnSpan="2" Margin="10,244,0,0"/>
                </Grid>
            </TabItem>
            <TabItem Header="Created Ticket">
                <Grid Background="#FFE5E5E5">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="10*"/>
                        <ColumnDefinition Width="35*"/>
                        <ColumnDefinition Width="399*"/>
                    </Grid.ColumnDefinitions>
                    <TextBox x:Name="ticketHeader" Grid.Column="1" HorizontalAlignment="Left" Margin="0,35,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="424" Grid.ColumnSpan="2" IsReadOnly="true"/>
                    <TextBox x:Name="ticketBody" Grid.Column="1" HorizontalAlignment="Left" Margin="0,80,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="424" Grid.ColumnSpan="2" Height="316" IsReadOnly="true"/>
                    <Label Grid.Column="1" Content="Short Description" Margin="0,10,309,0" VerticalAlignment="Top" Grid.ColumnSpan="2" FontWeight="Bold"/>
                    <Label Grid.Column="1" Content="Ticket Body" Margin="0,54,309,0" VerticalAlignment="Top" Grid.ColumnSpan="2" FontWeight="Bold"/>
                    <Button x:Name="btnGenTicket" Grid.Column="2" Content="Generate" HorizontalAlignment="Left" Margin="311,8,0,0" VerticalAlignment="Top" Width="65"/>
                </Grid>
            </TabItem>
        </TabControl>
    </Grid>
</Window>
"@

$reader = (New-Object System.Xml.XmlNodeReader $xaml)
$window = [Windows.Markup.XamlReader]::Load($reader)
$xaml.SelectNodes("//*[@Name]") | ForEach-Object{
    try{
        Set-Variable -Name "var_$($_.Name)" -Value $window.FindName($_.Name) -ErrorAction Stop
    }
    catch{
        throw
    }
}

$var_ticketHeader.Text="test"

$var_btnGenTicket.Add_Click({
    if(!$var_imgBtn.Checked -and !$var_reimgBtn.Checked){
        $var_ticketHeader.Text="Please review the ticket information!"
        $var_ticketBody.Text="Please review the ticket information!"
    }
    elseif(!$var_blkTag.Checked -and !$var_whtTag.Checked -and !$var_bthTag.Checked){
        $var_ticketHeader.Text="Please review the ticket information!"
        $var_ticketBody.Text="Please review the ticket information!"
    }
    elseif(!$var_lapTop.Checked -and !$var_deskTop.Checked){
        $var_ticketHeader.Text="Please review the ticket information!"
        $var_ticketBody.Text="Please review the ticket information!"
    }
    else{
        $var_ticketHeader.Text="Hooray! Radio buttons are working!"
        $var_ticketBody.Text="Hooray! Radio buttons are working!"
    }

})

$Null = $window.ShowDialog()

我试图让它工作的代码是:

$xaml.SelectNodes("//*[@Name]") | ForEach-Object{
    try{
        Set-Variable -Name "var_$($_.Name)" -Value $window.FindName($_.Name) -ErrorAction Stop
    }
    catch{
        throw
    }
}

我不知道为什么这不起作用,或者我做错了什么。如果你能帮忙的话,我将不胜感激。

y4ekin9u

y4ekin9u1#

$xaml.SelectNodes("//*[@Name]")
不起作用,因为输入XAML文档中的Name属性是 * 命名空间限定的 *(x:Name
为了通过传递给.SelectNodes()的查询来查询这些属性,您需要:

  • 传递一个 namespace manager 对象作为第二个参数,其中与输入文档中相同的命名空间 URI Map到 prefix(也可以是x,但不是必须是)。
  • 请在SQL查询中使用该前缀限定属性引用。

把它拼出来:

# Create a namespace manager for the input document.
$nsMgr = [System.Xml.XmlNamespaceManager]::new($xaml.NameTable)

# Add the relevant URI for the Name attributes, using a self-chosen
# prefix that may be but needn't be the same as in the input document.
$nsMgr.AddNamespace('x', 'http://schemas.microsoft.com/winfx/2006/xaml')

# Use the self-chosen prefix in the XPath query.
$xaml.SelectNodes("//*[@x:Name]", $nsMgr) |
  ForEach-Object{
    # Create a var_* variable for every control in the window, named for that control.
    Set-Variable -Name "var_$($_.Name)" -Value $window.FindName($_.Name)
  }
72qzrwbm

72qzrwbm2#

尝试使用Xml Linq

using assembly System.Xml.Linq
$xaml = @"
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ImagingInfoSample"
        Title="Imaging Ticket Creator" Height="500" Width="500">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="b2v" />
    </Window.Resources>
    <Grid>
        <TabControl>
            <TabItem Header="Ticket Information">
                <Grid Background="#FFE5E5E5">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="101*"/>
                        <ColumnDefinition Width="23*"/>
                        <ColumnDefinition Width="320*"/>
                    </Grid.ColumnDefinitions>
                    <StackPanel Margin="11" Width="300" Grid.ColumnSpan="3" HorizontalAlignment="Left">
                        <StackPanel.Resources>
                            <Style TargetType="{x:Type RadioButton}">
                                <Setter Property="Margin" Value="0,10,0,0"/>
                            </Style>
                        </StackPanel.Resources>
                        <Label FontWeight="Bold" Content="Imaging or Reimaging?"></Label>
                        <RadioButton x:Name="imgBtn" GroupName="jobType">Imaging</RadioButton>
                        <RadioButton x:Name ="reimgBtn" GroupName="jobType">Reimaging</RadioButton>
                        <Label FontWeight="Bold" Content="Make:" ></Label>
                        <Label FontWeight="Bold" Content="Model:"></Label>
                        <Label FontWeight="Bold" Content="Tag Type/Number:"></Label>
                        <RadioButton x:Name="blkTag" GroupName="tagType">Black Tag</RadioButton>
                        <RadioButton x:Name="whtTag" GroupName="tagType">White Tag</RadioButton>
                        <RadioButton x:Name="bthTag" GroupName="tagType">Both (Fill in both boxes above if selecting this)</RadioButton>
                        <Label FontWeight="Bold" Content="Serial Number:"></Label>
                        <Label FontWeight="Bold" Content="Laptop or Desktop?"></Label>
                        <RadioButton x:Name="lapTop" GroupName="lapOrDesk">Laptop</RadioButton>
                        <RadioButton x:Name="deskTop" GroupName="lapOrDesk">Desktop</RadioButton>
                    </StackPanel>
                    <TextBox x:Name="compMake" Grid.Column="1" HorizontalAlignment="Left" Margin="0,92,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Grid.ColumnSpan="2"/>
                    <TextBox x:Name="compModel" Grid.Column="1" HorizontalAlignment="Left" Margin="0,115,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Grid.ColumnSpan="2"/>
                    <TextBox x:Name="blackTagBox" HorizontalAlignment="Left" Margin="0,176,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Grid.ColumnSpan="2" Grid.Column="1"/>
                    <TextBox x:Name="whiteTagBox" Grid.Column="1" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Grid.ColumnSpan="2" Margin="0,199,0,0"/>
                    <TextBox x:Name="snBox" Grid.Column="1" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Grid.ColumnSpan="2" Margin="10,244,0,0"/>
                </Grid>
            </TabItem>
            <TabItem Header="Created Ticket">
                <Grid Background="#FFE5E5E5">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="10*"/>
                        <ColumnDefinition Width="35*"/>
                        <ColumnDefinition Width="399*"/>
                    </Grid.ColumnDefinitions>
                    <TextBox x:Name="ticketHeader" Grid.Column="1" HorizontalAlignment="Left" Margin="0,35,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="424" Grid.ColumnSpan="2" IsReadOnly="true"/>
                    <TextBox x:Name="ticketBody" Grid.Column="1" HorizontalAlignment="Left" Margin="0,80,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="424" Grid.ColumnSpan="2" Height="316" IsReadOnly="true"/>
                    <Label Grid.Column="1" Content="Short Description" Margin="0,10,309,0" VerticalAlignment="Top" Grid.ColumnSpan="2" FontWeight="Bold"/>
                    <Label Grid.Column="1" Content="Ticket Body" Margin="0,54,309,0" VerticalAlignment="Top" Grid.ColumnSpan="2" FontWeight="Bold"/>
                    <Button x:Name="btnGenTicket" Grid.Column="2" Content="Generate" HorizontalAlignment="Left" Margin="311,8,0,0" VerticalAlignment="Top" Width="65"/>
                </Grid>
            </TabItem>
        </TabControl>
    </Grid>
</Window>
"@
$doc = [System.Xml.Linq.XDocument]::Parse($xaml)
$xNs = $doc.Root.GetNamespaceOfPrefix('x')
$descendants = $doc.Descendants()
$named = [System.Linq.Enumerable]::Where($descendants, [Func[object,bool]]{ param($x) $x.Attribute($xns + "Name") -ne $null})

$table =  [System.Collections.ArrayList]@()
foreach($name in $named)
{
   $newRow = [pscustomobject]@{
      'Tag Name'=$name.Name.LocalName
      Name=$name.Attribute($xns + "Name").Value
      Value=$name.value
   }
   $table.Add($newRow)  | Out-Null
}
$table | Format-Table

结果

Tag Name    Name         Value
--------    ----         -----
RadioButton imgBtn       Imaging
RadioButton reimgBtn     Reimaging
RadioButton blkTag       Black Tag
RadioButton whtTag       White Tag
RadioButton bthTag       Both (Fill in both boxes above if selecting this)
RadioButton lapTop       Laptop
RadioButton deskTop      Desktop
TextBox     compMake
TextBox     compModel
TextBox     blackTagBox
TextBox     whiteTagBox
TextBox     snBox
TextBox     ticketHeader
TextBox     ticketBody
Button      btnGenTicket

相关问题