【问题标题】:Make Visual Studio XAML output compatible to System.Windows.Markup.XamlReader使 Visual Studio XAML 输出与 System.Windows.Markup.XamlReader 兼容
【发布时间】:2016-04-17 21:38:10
【问题描述】:

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

问题是,一些基本的控件是好的(在一些替换之后),但是一旦你在 VS 中配置了更多的属性,当你用 XAMLreader 加载 XAML 时,你就会得到源源不断的错误。
示例question 的答案在 VisualStudio 中运行良好,但在通过 Xamlreader 加载时会产生很多错误。

  • 那么,为什么它不起作用? System.Windows.Markup.XamlReadersupposed 遵循与 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()

【问题讨论】:

  • 究竟是哪些错误?我希望像x:Class 这样的引用会引发错误,因为 PowerShell 没有关联的类
  • 说“让它工作”然后说“哪个特定错误都没有关系”是没有意义的。我们只能修复您告诉我们的错误。
  • @Moss 去掉x:Classmc:Ignorable属性并关闭Window标签,完成

标签: wpf visual-studio xaml powershell


【解决方案1】:

如 cmets 中所述,您提供的示例很容易适用于非 VS 运行时。

  1. 删除x:Class 属性,因为我们没有定义相应的类
  2. 删除mc:Ignorable 属性,因为它无法解析
  3. 添加关闭 &lt;/Window&gt; 标记,原始示例中缺少:

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


为了完整起见,answer 中您链接到的问题的示例:

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

【讨论】:

  • 您没有从 ANSWER 中获取代码。正如我所说,随着 xaml 复杂性的增加,问题变得更加严重。
  • 由于 -replace 'x:N','N' - 您正在破坏 Name 属性的命名空间引用和 {x:Null} 值引用
  • 就是这样。似乎我对许多错误的印象仅仅是由于指向错误方向的无用错误消息。再次感谢我的无知。
  • @Moss 不用担心,很乐意提供帮助 :-)
猜你喜欢
  • 2018-04-19
  • 2019-08-07
  • 1970-01-01
  • 1970-01-01
  • 2015-07-30
  • 2017-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多