使用XSLT 1.0进行XML到XAML转换|排除特定的转换对于某些控件

问题描述:

让说我有以下XML代码使用XSLT 1.0进行XML到XAML转换|排除特定的转换对于某些控件

<PanelWrapper id="RootPanel" 
       width="800" 
       height="600" 
       forecolor="Black"> 
    <ButtonWrapper id="button" 
        text="click!" 
        forecolor="Black"> 
     <TabIndex>0</TabIndex> 
     <TabStop>True</TabStop> 
    </ButtonWrapper> 
</PanelWrapper> 

此代码应使用XSLT 1.0转化为XAML代码:

<WrapPanel Name="RootPanel" 
      Width="800" 
      Height="600"> 
    <Button Name="button" 
      Content="click!" 
      Foreground="Black" 
      TabIndex="0" 
      IsTabStop="True"> 
    </Button> 
</WrapPanel> 

我目前使用这个样式表:(简体版)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/> 

    <!-- Transform PanelWrapper to WrapPannel --> 
    <xsl:template match="PanelWrapper"> 
     <WrapPanel> 
      <xsl:apply-templates select="@*|*" /> 
     </WrapPanel> 
    </xsl:template> 

    <!-- Transform ButtonWrapper to Button --> 
    <xsl:template match="ButtonWrapper"> 
     <Button> 
      <xsl:apply-templates select="@*" /> 
     </Button> 
    </xsl:template> 

    <!-- some other mapping for id(name), height, weight, text --> 

    <!-- Map forecolor to Foreground --> 
    <xsl:template match="@forecolor"> 
     <xsl:attribute name="Foreground"> 
      <xsl:value-of select="." /> 
     </xsl:attribute> 
    </xsl:template> 

</xsl:stylesheet> 

我目前看到的结果如下:

<WrapPanel Name="RootPanel" 
      Width="800" 
      Height="600" 
      Foreground="Black"> //unwanted, Problem 1 
    <Button Name="button" 
      Content="click!" 
      Foreground="Black"> 
    </Button> 
      0 //Problem 2 
     True //Problem 2 
</WrapPanel> 

问题1: 的WrapPanel在XAML没有前景属性,但因为有我的XML源代码中定义的前景色文件,它是为WrapPanel产生太大。我该如何解决这个问题?

问题2: 如何解决TabIndex和IsTabStop问题?

编辑:让我澄清的问题2. 这是XML输入:

<ButtonWrapper id="button" 
       text="click!" 
       forecolor="Black"> 
    <TabIndex>0</TabIndex> 
    <TabStop>True</TabStop> 
</ButtonWrapper> 

,这是输出我尽量做到:

<Button Name="button" 
     Content="click!" 
     Foreground="Black" 
     TabIndex="0" 
     IsTabStop="True"> 
</Button> 

问题1。您可以添加以下模板

<xsl:template match="PanelWrapper/@forecolor" /> 

这将为所有PanelWrapper元素排除名为forecolor的属性。

问题2。要解决第二个问题,必须分别使用以下XPath表达式匹配所有TabIndex元素和某些元素的子元素的TabStop元素:*/TabIndex,*/TabStop。然后你可以将该元素映射到一个属性。

下转型实现你想要什么:

<!-- Transform element TabIndex to an attribute with the same 
    name in its parent --> 
<xsl:template match="*/TabIndex"> 
    <xsl:attribute name="TabIndex"> 
     <xsl:value-of select="." /> 
    </xsl:attribute> 
</xsl:template> 

<!-- Transform element TabStop to an attribute with the name 
    IsTabStop in its parent --> 
<xsl:template match="*/TabStop"> 
    <xsl:attribute name="IsTabStop"> 
     <xsl:value-of select="." /> 
    </xsl:attribute> 
</xsl:template> 

更新。为完整的XML添加解决方案。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/> 
    <!-- special thanks to: Pablo Pozo --> 

    <xsl:variable name="attributeMap" 
        select="'|font-size,FontSize|font-name,FontFamily|enabled,isEnabled|forecolor,Foreground|id,name|TabStop,IsTabStop|TabIndex,isTabIndex|dock,DockPanel.Dock|width,Width|height,Height|'" /> 

    <!--      --> 
    <!-- Default processing  --> 
    <!--      --> 

    <!-- Ignore attributes by default, so we can have more control 
     about unhandled attributes --> 
    <xsl:template match="@*|*" /> 
    <xsl:template match="node()|@*" mode="to-attr"/> 

    <!-- Default attribute processing --> 
    <xsl:template name="process-element"> 
     <xsl:param name="attr" /> 

     <!-- Process all attributes and elements which are going to be 
      transformed to attributes --> 
     <xsl:apply-templates select="@*|*" mode="to-attr" /> 
     <!-- Add extra attribute --> 
     <xsl:if test="$attr"> 
      <xsl:attribute name="{substring-after($attr, '|')}"> 
       <xsl:value-of select="@*[local-name() = substring-before($attr, '|')]" /> 
      </xsl:attribute> 
     </xsl:if> 
     <!-- Process children elements --> 
     <xsl:apply-templates select="*" /> 
    </xsl:template> 

    <!--      --> 
    <!-- Control transformations--> 
    <!--      --> 

    <!-- Transform PanelWrapper to WrapPannel --> 
    <xsl:template match="PanelWrapper"> 
     <WrapPanel> 
      <xsl:call-template name="process-element" /> 
     </WrapPanel> 
    </xsl:template> 

    <!-- Exclude attributes for PanelWrapper --> 
    <xsl:template match="PanelWrapper/@forecolor|PanelWrapper/@font-name|PanelWrapper/@font-size|PanelWrapper/@font-style" 
        mode="to-attr" /> 
    <!-- TODO: Exclude doesn't work for the following attributes --> 
    <xsl:template match="PanelWrapper/@border-left|PanelWrapper/@border-top|PanelWrapper/@border-right|PanelWrapper/@border-bottom" 
        mode="to-attr" /> 

    <!-- Transform DropDownWrapper to ComboBox --> 
    <xsl:template match="DropDownWrapper"> 
     <ComboBox> 
      <xsl:call-template name="process-element"> 
       <xsl:with-param name="attr" select="'text|Text'" /> 
      </xsl:call-template> 
     </ComboBox> 
    </xsl:template> 

    <!-- Exclude attributes for ComboBox --> 
    <!-- Transform GroupBoxWrapper to GroupBox --> 

    <!-- Map GroupBoxWrapper, LabelWrapper, TextBoxWrapper, ButtonWrapper into 
     elements with their prefix as their name --> 
    <xsl:template match="GroupBoxWrapper|LabelWrapper|TextBoxWrapper|ButtonWrapper"> 
     <xsl:element name="{substring-before(local-name(), 'Wrapper')}"> 
      <xsl:call-template name="process-element"> 
       <xsl:with-param name="attr" select="'text|Content'" /> 
      </xsl:call-template> 
     </xsl:element> 
    </xsl:template> 

    <!-- Exclude attributes for GroupBox --> 
    <!-- Exclude attributes for Label --> 
    <!-- Exclude attributes for Text --> 
    <!-- TODO: invalid value for Background attribute, eg: Background="window" --> 
    <!-- Exclude attributes for Button --> 
    <!-- TODO: invalid value for Background attribute, eg: Background="buttonface" --> 


    <!-- Map RadioButtonViewWrapper, CheckBoxViewWrapper into elements 
     with their prefix as their name --> 
    <xsl:template match="RadioButtonViewWrapper|CheckBoxViewWrapper"> 
     <xsl:element name="{substring-before(local-name(), 'ViewWrapper')}"> 
      <xsl:call-template name="process-element"> 
       <xsl:with-param name="attr" select="'text|Content'" /> 
      </xsl:call-template> 
     </xsl:element> 
    </xsl:template> 


    <!-- Exclude attributes for RadioButton --> 
    <!-- Exclude attributes for CheckBox --> 


    <!--       --> 
    <!-- Attributes transformations--> 
    <!--       --> 

    <!-- Transform elements which just map the name of the attribute to a different name --> 
    <xsl:template match="@font-size|@font-name|@enabled|@forecolor|@id|TabStop|TabIndex|@dock|@width|@height" 
        mode="to-attr"> 
     <!-- Look in map for the transformation --> 
     <xsl:variable name="new-attribute" 
         select="substring-before(substring-after($attributeMap, concat('|', local-name(), ',')), '|')" /> 
     <xsl:attribute name="{$new-attribute}"> 
      <xsl:value-of select="." /> 
     </xsl:attribute> 
    </xsl:template> 

    <!-- OVERRIDE!! Back color: not sure of the logic here.--> 
    <xsl:template match="@backcolor" mode="to-attr"> 
     <xsl:attribute name="Background">Grey</xsl:attribute> 
    </xsl:template> 

    <!-- Ignore TabIndex and TabStop within PanelWrapper --> 
    <xsl:template match="PanelWrapper/TabIndex|PanelWrapper/TabStop" mode="to-attr" /> 

    <!-- Map @dock = 'Fill' to @dock = 'Left, Right...etc' --> 
    <xsl:template match="@dock[. = 'Fill']" mode="to-attr" > 
     <xsl:attribute name="DockPanel.Dock"> 
      <xsl:value-of select="'Left, Right, Top, Bottom'" /> 
     </xsl:attribute> 
    </xsl:template> 

    <!-- Map visible attribute to Visibility --> 
    <xsl:template match="@visible[. = 'True']" mode="to-attr" > 
     <xsl:attribute name="Visibility">visible</xsl:attribute> 
    </xsl:template> 

    <xsl:template match="@visible[. = 'False']" mode="to-attr" > 
     <xsl:attribute name="Visibility">hidden</xsl:attribute> 
    </xsl:template> 

    <!-- Build the border attribute --> 
    <xsl:template match="@*[starts-with(local-name(), 'border-')][1]" mode="to-attr"> 
     <xsl:attribute name="BorderThickness"> 
      <!-- Print the border-elements in a comma separated list (non-defined attributes default 
       to zero) --> 
      <xsl:call-template name="border-print" /> 
     </xsl:attribute> 
    </xsl:template> 

    <!-- Recursive template to group borders in BorderThickness --> 
    <xsl:template name="border-print"> 
     <!-- Do not remove spaces in the next line! --> 
     <xsl:param name="string" select="'left top right bottom'" /> 
     <xsl:param name="parent" select=".." /> 
     <xsl:param name="not-first" select="false()" /> 

     <xsl:if test="$string != ''"> 
      <!-- Obtain next direction --> 
      <xsl:variable name="direction" select="normalize-space(substring($string, 1, 6))" /> 
      <xsl:variable name="attr" select="$parent/@*[local-name() = concat('border-', $direction)]" /> 
      <!-- Print comma if not the first element --> 
      <xsl:if test="$not-first"><xsl:text>,</xsl:text></xsl:if> 
      <!-- Print zero if the attribute cannot be found --> 
      <xsl:choose> 
       <!-- Attribute found : print --> 
       <xsl:when test="$attr"> 
        <xsl:value-of select="$attr" /> 
       </xsl:when> 
       <!-- Attribute not found: print 0 --> 
       <xsl:otherwise> 
        <xsl:text>0</xsl:text> 
       </xsl:otherwise> 
      </xsl:choose> 
      <!-- Recurse --> 
      <xsl:call-template name="border-print"> 
       <xsl:with-param name="string" select="substring($string, 7)" /> 
       <xsl:with-param name="parent" select="$parent" /> 
       <xsl:with-param name="not-first" select="true()" /> 
      </xsl:call-template> 
     </xsl:if> 

    </xsl:template> 

    <xsl:template match="@*" mode="print-border"> 
     <xsl:value-of select="concat(., ',')" /> 
    </xsl:template> 

    <xsl:template match="@border-bottom" mode="print-border"> 
     <xsl:value-of select="." /> 
    </xsl:template> 

    <!-- 
    <xsl:template match="@font-style[. = 'Regular']"> 
     <xsl:attribute name="FontStyle">Normal</xsl:attribute> 
    </xsl:template> 
    --> 
    <!-- TODO: condition is invalid, chooses Italic for everything--> 
    <xsl:template match="@font-style" mode="to-attr"> 
     <xsl:choose> 
      <xsl:when test="'Italic'"> 
       <xsl:attribute name="FontStyle">Italic</xsl:attribute> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:attribute name="FontStyle">Normal</xsl:attribute> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 
+0

感谢您解决第一个问题。我想我没有足够好地解释第二个问题。我希望在我最后一次编辑后它变得更加清晰。 – Joel 2013-02-28 08:43:22

+0

对不起,我很快就读了你的文章,我没有意识到你正试图将元素转换为属性。我更新了答案。 – 2013-02-28 09:44:15

+0

问题2导致未处理的XslTransformException“在添加了文本,注释,pi或子元素节点后,无法将属性和命名空间节点添加到父元素中。” – Joel 2013-02-28 10:18:04

问题1:了borderThickness,仍显示为WrapPanels [解决]

解决方案:该模板只要求所有元件,但PanelWrapper。 (见如果条件)

<xsl:template match="@*[starts-with(local-name(), 'border-')][1]" mode="to-attr"> 
    <xsl:if test="not(parent::PanelWrapper)"> 
     <xsl:attribute name="BorderThickness"> 
      <!--Print the border-elements in a comma separated list (non-defined attributes default 
       to zero)--> 
      <xsl:call-template name="border-print" /> 
     </xsl:attribute> 
     </xsl:if> 
    </xsl:template> 

问题2:由于WPF的组框中只接受一个控制我不得不所有属性第一包装成一个网格控制。我认为这不会有什么大不了,但事实证明groupbox属性被添加到网格控件中。

这里谈到的(更新的)XSL样式表:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/> 
<!-- very special thanks to: Pablo Pozo --> 
    <xsl:variable name="attributeMap" 
       select="'|font-size,FontSize|font-name,FontFamily|enabled,isEnabled|forecolor,Foreground|id,Name|TabStop,IsTabStop|TabIndex,TabIndex|dock,DockPanel.Dock|width,Width|height,Height|'" /> 

    <!-- Ignore attributes by default, so we can have more control 
     about unhandled attributes --> 
    <xsl:template match="@*|*" /> 
    <xsl:template match="node()|@*" mode="to-attr"/> 

    <!-- Default attribute processing --> 
    <xsl:template name="process-element"> 
    <xsl:param name="attr" /> 

    <!-- Process all attributes and elements which are going to be 
      transformed to attributes --> 
    <xsl:apply-templates select="@*|*" mode="to-attr" /> 
    <!-- Add extra attribute --> 
    <xsl:if test="$attr"> 
     <xsl:attribute name="{substring-after($attr, '|')}"> 
     <xsl:value-of select="@*[local-name() = substring-before($attr, '|')]" /> 
     </xsl:attribute> 
    </xsl:if> 
    <!-- Process children elements --> 
    <xsl:apply-templates select="*" /> 
    </xsl:template> 

    <!-- Transform PanelWrapper to WrapPannel --> 
    <xsl:template match="PanelWrapper"> 
    <WrapPanel> 
     <xsl:call-template name="process-element" /> 
    </WrapPanel> 
    </xsl:template> 

    <!-- Exclude attributes for PanelWrapper --> 
    <xsl:template match="PanelWrapper/@forecolor|PanelWrapper/@font-name|PanelWrapper/@font-size|PanelWrapper/@font-style" 
       mode="to-attr" /> 
    <xsl:template match="PanelWrapper/@border-left|PanelWrapper/@border-top|PanelWrapper/@border-right|PanelWrapper/@border-bottom" 
       mode="to-attr" /> 
    <xsl:template match="PanelWrapper/TabIndex|PanelWrapper/TabStop" 
       mode="to-attr" /> 

    <!-- Transform DropDownWrapper to ComboBox --> 
    <xsl:template match="DropDownWrapper"> 
    <ComboBox> 
     <xsl:call-template name="process-element"> 
     <xsl:with-param name="attr" select="'text|Text'" /> 
     </xsl:call-template> 
    </ComboBox> 
    </xsl:template> 

    <!-- Map GroupBoxWrapper into 
     elements with their prefix as their name --> 
    <xsl:template match="GroupBoxWrapper"> 
    <xsl:element name="GroupBox"> 
     <Grid> 
     <xsl:call-template name="process-element"> 
     <xsl:with-param name="attr"/> 
     </xsl:call-template> 
     </Grid> 
    </xsl:element> 
    </xsl:template> 

    <!-- Map LabelWrapper, ButtonWrapper into 
     elements with their prefix as their name --> 
    <xsl:template match="LabelWrapper|ButtonWrapper"> 
    <xsl:element name="{substring-before(local-name(), 'Wrapper')}"> 
     <xsl:call-template name="process-element"> 
     <xsl:with-param name="attr" select="'text|Content'" /> 
     </xsl:call-template> 
    </xsl:element> 
    </xsl:template> 

    <!-- Map TextBoxWrapper into 
      elements with their prefix as their name --> 
    <xsl:template match="TextBoxWrapper"> 
    <xsl:element name="{substring-before(local-name(), 'Wrapper')}"> 
     <xsl:call-template name="process-element"> 
     <xsl:with-param name="attr" select="'text|Text'" /> 
     </xsl:call-template> 
    </xsl:element> 
    </xsl:template> 

    <!-- Map RadioButtonViewWrapper, CheckBoxViewWrapper into elements 
     with their prefix as their name --> 
    <xsl:template match="RadioButtonViewWrapper|CheckBoxViewWrapper"> 
    <xsl:element name="{substring-before(local-name(), 'ViewWrapper')}"> 
     <xsl:call-template name="process-element"> 
     <xsl:with-param name="attr" select="'text|Content'" /> 
     </xsl:call-template> 
    </xsl:element> 
    </xsl:template> 

    <!--       --> 
    <!-- Attributes transformations--> 
    <!--       --> 

    <!-- Transform elements which just map the name of the attribute to a different name --> 
    <xsl:template match="@font-size|@font-name|@enabled|@forecolor|@id|TabStop|TabIndex|@width|@height" 
       mode="to-attr"> 
    <!-- Look in map for the transformation --> 
    <xsl:variable name="new-attribute" 
        select="substring-before(substring-after($attributeMap, concat('|', local-name(), ',')), '|')" /> 
    <xsl:attribute name="{$new-attribute}"> 
     <xsl:value-of select="." /> 
    </xsl:attribute> 
    </xsl:template> 

    <!-- Transform dock element --> 
    <xsl:template match="@dock" mode="to-attr"> 
    <xsl:choose> 
     <xsl:when test=". = 'Fill'"> 
     <xsl:attribute name="DockPanel.Dock"> 
      <xsl:value-of select="'Left, Right, Top, Bottom'" /> 
     </xsl:attribute> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:if test=". != 'None'"> 
      <xsl:attribute name="DockPanel.Dock"> 
      <xsl:value-of select="." /> 
      </xsl:attribute> 
     </xsl:if> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

    <!-- Transform Visual Web GUI Colors to XAML conform values.--> 
    <xsl:template match="@backcolor" mode="to-attr"> 
    <xsl:choose> 
     <xsl:when test=". = 'buttonface'"> 
     <xsl:attribute name="Background">Azure</xsl:attribute> 
     </xsl:when> 
     <xsl:when test=". = 'window'"> 
     <xsl:attribute name="Background">Azure</xsl:attribute> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:attribute name="Background"> 
      <xsl:value-of select="." /> 
     </xsl:attribute> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

    <!-- Map visible attribute to Visibility --> 
    <xsl:template match="@visible[. = 'True']" mode="to-attr" > 
    <xsl:attribute name="Visibility">visible</xsl:attribute> 
    </xsl:template> 

    <xsl:template match="@visible[. = 'False']" mode="to-attr" > 
    <xsl:attribute name="Visibility">hidden</xsl:attribute> 
    </xsl:template> 

    <!-- Build the border attribute --> 
    <xsl:template match="@*[starts-with(local-name(), 'border-')][1]" mode="to-attr"> 
    <xsl:attribute name="BorderThickness"> 
     <!-- Print the border-elements in a comma separated list (non-defined attributes default 
       to zero) --> 
     <xsl:call-template name="border-print" /> 
    </xsl:attribute> 
    </xsl:template> 

    <!-- Recursive template to group borders in BorderThickness --> 
    <xsl:template name="border-print"> 
    <!-- Do not remove spaces in the next line! --> 
    <xsl:param name="string" select="'left top right bottom'" /> 
    <xsl:param name="parent" select=".." /> 
    <xsl:param name="not-first" select="false()" /> 

    <xsl:if test="$string != ''"> 
     <!-- Obtain next direction --> 
     <xsl:variable name="direction" select="normalize-space(substring($string, 1, 6))" /> 
     <xsl:variable name="attr" select="$parent/@*[local-name() = concat('border-', $direction)]" /> 
     <!-- Print comma if not the first element --> 
     <xsl:if test="$not-first"> 
     <xsl:text>,</xsl:text> 
     </xsl:if> 
     <!-- Print zero if the attribute cannot be found --> 
     <xsl:choose> 
     <!-- Attribute found : print --> 
     <xsl:when test="$attr"> 
      <xsl:value-of select="$attr" /> 
     </xsl:when> 
     <!-- Attribute not found: print 0 --> 
     <xsl:otherwise> 
      <xsl:text>0</xsl:text> 
     </xsl:otherwise> 
     </xsl:choose> 
     <!-- Recurse --> 
     <xsl:call-template name="border-print"> 
     <xsl:with-param name="string" select="substring($string, 7)" /> 
     <xsl:with-param name="parent" select="$parent" /> 
     <xsl:with-param name="not-first" select="true()" /> 
     </xsl:call-template> 
    </xsl:if> 

    </xsl:template> 

    <xsl:template match="@*" mode="print-border"> 
    <xsl:value-of select="concat(., ',')" /> 
    </xsl:template> 

    <xsl:template match="@border-bottom" mode="print-border"> 
    <xsl:value-of select="." /> 
    </xsl:template> 

    <!-- Mapping font-style to FontStyle --> 
    <!-- Convert values to valid XAML values --> 
    <xsl:template match="@font-style"> 
    <xsl:choose> 
     <xsl:when test=". = 'Italic'"> 
     <xsl:attribute name="FontStyle">Italic</xsl:attribute> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:attribute name="FontStyle">Normal</xsl:attribute> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 

这里谈到这应被转换成XAML代码

<PanelWrapper id="RootPanel" dock="Fill" text="" theme="" width="1412" height="605" backcolor="Transparent" forecolor="Black" visible="True" mapNode="" border-left="0" border-top="0" border-right="0" border-bottom="0" font-name="Tahoma" font-size="8,25" font-style="Regular"> 
    <PanelWrapper id="panel1" dock="None" text="" theme="" width="800" height="400" backcolor="Transparent" forecolor="Black" visible="True" mapNode="" border-left="1" border-top="1" border-right="1" border-bottom="1" font-name="Tahoma" font-size="9" font-style="Regular"> 
    <GroupBoxWrapper id="groupbox1" dock="Bottom" text="" theme="" width="796" height="300" backcolor="Transparent" forecolor="#0046D5" visible="True" mapNode="" border-left="1" border-top="1" border-right="1" border-bottom="1" font-name="Tahoma" font-size="9" font-style="Regular"> 
     <RadioButtonViewWrapper id="radiobutton1" dock="Top" text="radiobox" theme="" width="484" height="100" backcolor="Transparent" forecolor="Black" visible="True" mapNode="" border-left="1" border-top="1" border-right="1" border-bottom="1" font-name="Tahoma" font-size="9" font-style="Regular"> 
     <TabIndex>1</TabIndex> 
     <TabStop>True</TabStop> 
     </RadioButtonViewWrapper> 
     <CheckBoxViewWrapper id="checkbox1" dock="Left" text="checkbox" theme="" width="75" height="177" backcolor="Transparent" forecolor="Black" visible="True" mapNode="" border-left="1" border-top="1" border-right="1" border-bottom="1" font-name="Tahoma" font-size="9" font-style="Regular"> 
     <TabIndex>2</TabIndex> 
     <TabStop>True</TabStop> 
     </CheckBoxViewWrapper> 
     <TabIndex>4</TabIndex> 
     <TabStop>False</TabStop> 
    </GroupBoxWrapper> 
    <PanelWrapper id="panel5" dock="Top" text="Click!" theme="" width="796" height="25" backcolor="Transparent" forecolor="Black" visible="True" mapNode="" border-left="1" border-top="1" border-right="1" border-bottom="1" font-name="Tahoma" font-size="9" font-style="Regular"> 
     <ButtonWrapper id="button2" dock="Left" text="click!" theme="" width="100" height="21" backcolor="buttonface" forecolor="Black" visible="True" mapNode="" border-left="1" border-top="1" border-right="1" border-bottom="1" font-name="Tahoma" font-size="9" font-style="Regular"> 
     <TabIndex>0</TabIndex> 
     <TabStop>True</TabStop> 
     </ButtonWrapper> 
     <TextBoxWrapper id="textbox2" dock="Left" text="textbox" theme="" width="100" height="21" backcolor="window" forecolor="Black" visible="True" mapNode="" border-left="1" border-top="1" border-right="1" border-bottom="1" font-name="Tahoma" font-size="9" font-style="Italic"> 
     <TabIndex>1</TabIndex> 
     <TabStop>True</TabStop> 
     </TextBoxWrapper> 
     <LabelWrapper id="label2" dock="Left" text="label" theme="" width="100" height="21" backcolor="Transparent" forecolor="Black" visible="True" mapNode="" border-left="1" border-top="1" border-right="1" border-bottom="1" font-name="Tahoma" font-size="9" font-style="Regular"> 
     <TabIndex>2</TabIndex> 
     <TabStop>False</TabStop> 
     </LabelWrapper> 
     <DropDownWrapper id="combobox2" dock="Left" text="combobox" theme="" width="100" height="21" backcolor="window" forecolor="Black" visible="True" mapNode="" border-left="1" border-top="1" border-right="1" border-bottom="1" font-name="Tahoma" font-size="9" font-style="Regular"> 
     <TabIndex>3</TabIndex> 
     <TabStop>True</TabStop> 
     </DropDownWrapper> 
     <TabIndex>5</TabIndex> 
     <TabStop>False</TabStop> 
    </PanelWrapper> 
    <TabIndex>0</TabIndex> 
    <TabStop>False</TabStop> 
    </PanelWrapper> 
    <TabIndex>0</TabIndex> 
    <TabStop>False</TabStop> 
</PanelWrapper> 

的XAML结果看起来像这样的XML文件:

<WrapPanel Name="RootPanel" DockPanel.Dock="Left, Right, Top, Bottom" Width="1412" Height="605" Background="Transparent" Visibility="visible" BorderThickness="0,0,0,0"> 
    <WrapPanel Name="panel1" Width="800" Height="400" Background="Transparent" Visibility="visible" BorderThickness="1,1,1,1"> 
    <GroupBox> 
     <Grid Name="groupbox1" DockPanel.Dock="Bottom" Width="796" Height="300" Background="Transparent" Foreground="#0046D5" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="4" IsTabStop="False"> 
     <RadioButton Name="radiobutton1" DockPanel.Dock="Top" Width="484" Height="100" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="1" IsTabStop="True" Content="radiobox" /> 
     <CheckBox Name="checkbox1" DockPanel.Dock="Left" Width="75" Height="177" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="2" IsTabStop="True" Content="checkbox" /> 
     </Grid> 
    </GroupBox> 
    <WrapPanel Name="panel5" DockPanel.Dock="Top" Width="796" Height="25" Background="Transparent" Visibility="visible" BorderThickness="1,1,1,1"> 
     <Button Name="button2" DockPanel.Dock="Left" Width="100" Height="21" Background="Azure" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="0" IsTabStop="True" Content="click!" /> 
     <TextBox Name="textbox2" DockPanel.Dock="Left" Width="100" Height="21" Background="Azure" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="1" IsTabStop="True" Text="textbox" /> 
     <Label Name="label2" DockPanel.Dock="Left" Width="100" Height="21" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="2" IsTabStop="False" Content="label" /> 
     <ComboBox Name="combobox2" DockPanel.Dock="Left" Width="100" Height="21" Background="Azure" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="3" IsTabStop="True" Text="combobox" /> 
    </WrapPanel> 
    </WrapPanel> 
</WrapPanel> 

预期的XAML代码应如下所示:

<WrapPanel Name="RootPanel" DockPanel.Dock="Left, Right, Top, Bottom" Width="1412" Height="605" Background="Transparent" Visibility="visible" > 
    <WrapPanel Name="panel1" Width="800" Height="400" Background="Transparent" Visibility="visible" > 
     <GroupBox Name="groupbox1" DockPanel.Dock="Bottom" Width="796" Height="300" Background="Transparent" Foreground="#0046D5" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="4" IsTabStop="False"> 
      <Grid> 
       <RadioButton Name="radiobutton1" DockPanel.Dock="Top" Width="484" Height="100" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="1" IsTabStop="True" Content="radiobox" /> 
       <CheckBox Name="checkbox1" DockPanel.Dock="Left" Width="75" Height="177" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="2" IsTabStop="True" Content="checkbox" /> 
      </Grid> 
     </GroupBox> 
     <WrapPanel Name="panel5" DockPanel.Dock="Top" Width="796" Height="25" Background="Transparent" Visibility="visible" > 
      <Button Name="button2" DockPanel.Dock="Left" Width="100" Height="21" Background="Azure" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="0" IsTabStop="True" Content="click!" /> 
      <TextBox Name="textbox2" DockPanel.Dock="Left" Width="100" Height="21" Background="Azure" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="1" IsTabStop="True" Text="textbox" /> 
      <Label Name="label2" DockPanel.Dock="Left" Width="100" Height="21" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="2" IsTabStop="False" Content="label" /> 
      <ComboBox Name="combobox2" DockPanel.Dock="Left" Width="100" Height="21" Background="Azure" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="3" IsTabStop="True" Text="combobox" /> 
     </WrapPanel> 
    </WrapPanel> 
</WrapPanel> 

BTW:巴勃罗·波佐,我欠至少两个你啤酒

+0

有一个问题:对于WrapPanel元素,TabIndex和TabStop元素必须被忽略? – 2013-02-28 12:38:34

+0

是的,那是真的 – Joel 2013-02-28 12:46:02

+0

我已经用完整的XML更新了我的解决方案。我已经使用了几种技术来减小文件大小(大约减少100行),但是我没有时间来解释这些技术。看看我发布的消息来源,如果你发现我做了什么有些困难,请问我(但是我恐怕从现在开始4个小时或更长时间我不能回答你)。 – 2013-02-28 13:26:15