使Visual Studio XAML输出与System.Windows.Markup.XamlReader

时间:2016-04-17 12:30:55

标签: wpf visual-studio xaml powershell

我正在尝试在 Visual Studio (2015)中创建 WPF GUI ,并将创建的XAML加载到 Powershell 中,通过[System.Windows.Markup.XamlReader]::load()方法。

问题是,一些基本控件很好(在一些替换后),但是一旦在VS中配置了更多属性,在使用XAMLreader加载XAML时就会出现无穷无尽的错误。
示例 :此question的答案在VisualStudio中运行正常,但在通过Xamlreader 加载时会产生大量错误。

  • 那么,为什么不起作用? System.Windows.Markup.XamlReader是。{ supposed遵循与VS生成的XAML相同的shema (至少它在标题中说明了。)

  • 如何使VS生成的XAML与...一致兼容 XamlReader?

  • 如果那是不可能的,那么加载VS是否有另一种方式 将XAML生成为Powershell?

编辑:示例:

# ~~~~~~~~~~~~ WPF ~~~~~~~~~~~~~
$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:Window3"

           Title="Window" Height="40" Width="40" ToolTip="Tooltip" Topmost="True" WindowStyle="None" AllowsTransparency="True" Background="Transparent" ResizeMode="CanResizeWithGrip" MaxWidth="100" MaxHeight="100" MinWidth="20" MinHeight="20">
    <Border BorderBrush="#FF000000" BorderThickness="1,1,1,1" CornerRadius="5,5,5,5" UseLayoutRounding="True">
    <Grid>
    <Grid.ColumnDefinitions>
         <ColumnDefinition/>
         <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Label x:Name="Backdrop" Grid.ColumnSpan="2" Content="Label" Margin="0,0,0,0" Foreground="{x:Null}" Background="#FFAD3838"/>
    <Button x:Name="Button1" Grid.Column="0" Content="" Margin="1" BorderThickness="0" Background="#FF3B87BD"/>
    <Button x:Name="Button2" Grid.Column="1" Content="" Margin="1" BorderThickness="0" Background="#FF59B483"/>
        </Grid>
    </Border>
</Window>
"@
#   Add Type
 Add-Type -AssemblyName PresentationCore,PresentationFramework,WindowsBase,system.windows.forms

#   read XAML
$inputXML = $Xaml -replace 'mc:Ignorable="d"','' -replace "x:N",'N'   
[XML]$script:WpfXml = $inputXML

#   Remove Class, Load Reader
$WpfXml.Window.RemoveAttribute(“x:Class”)
$Reader = New-Object System.Xml.XmlNodeReader $WpfXml
$WpfForm = [Windows.Markup.XamlReader]::Load($Reader) 
$WpfXml.SelectNodes("//*[@Name]") | %{  Set-Variable -Name ($_.Name) -Value $WpfForm.FindName($_.Name) -Scope script  }


$WpfForm.showdialog()

1 个答案:

答案 0 :(得分:2)

正如评论中所提到的,您提供的示例非常容易适用于非VS运行时。

  1. 删除x:Class属性,因为我们没有定义相应的类
  2. 删除mc:Ignorable属性,因为无法解析
  3. 添加原始示例中缺少的结束</Window>标记:
  4. $null = [System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
    
    $NodeReader = New-Object System.Xml.XmlNodeReader $([xml]@'
    <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:ExampleWin"
        Title="Window" Height="200" Width="200" ToolTip="Tooltip" Topmost="True" WindowStyle="None" AllowsTransparency="True" Background="Transparent" ResizeMode="CanResizeWithGrip">
    <Border BorderBrush="#FF000000" BorderThickness="1,1,1,1" CornerRadius="5,5,5,5" UseLayoutRounding="True">
        <Grid>
            <Label x:Name="Backdrop" Content="Label" Margin="0,0,0,0" Foreground="{x:Null}" Background="#FFAD3838"/>
            <Button x:Name="Button1" Content="" Margin="1,1,99,1" BorderThickness="0" Background="#FF3B87BD"/>
            <Button x:Name="Button2" Content="" Margin="99,1,1,1" BorderThickness="0" Background="#FF59B483"/>
        </Grid>
    </Border>
    </Window>
    '@)
    
    $Window = [System.Windows.Markup.XamlReader]::Load($NodeReader)
    $Window.ShowDialog()
    

    enter image description here

    为了完整性,从回答到您链接的问题的示例:

    $null = [System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
    
    $NodeReader = New-Object System.Xml.XmlNodeReader $([xml]@'
    <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:ExampleWin"
        Title="Window" Height="200" Width="200" ToolTip="Tooltip" Topmost="True" WindowStyle="None" AllowsTransparency="True" Background="Transparent" ResizeMode="CanResizeWithGrip">
    <Border BorderBrush="#FF000000" BorderThickness="1,1,1,1" CornerRadius="5,5,5,5" UseLayoutRounding="True">
    <Grid>
        <Grid.ColumnDefinitions>
             <ColumnDefinition/>
             <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
    
        <Label x:Name="Backdrop" Grid.ColumnSpan="2" Content="Label" Margin="0,0,0,0" Foreground="{x:Null}" Background="#FFAD3838"/>
        <Button x:Name="Button1" Grid.Column="0" Content="" Margin="1" BorderThickness="0" Background="#FF3B87BD"/>
        <Button x:Name="Button2" Grid.Column="1" Content="" Margin="1" BorderThickness="0" Background="#FF59B483"/>
    </Grid>
    </Border>
    </Window>
    '@)
    
    $Window = [System.Windows.Markup.XamlReader]::Load($NodeReader)
    $Window.ShowDialog()
    

    enter image description here