2013-02-27 58 views
0

讓說我有以下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

問題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

0

問題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