The page that displays the delivery costs is relatively simple. However, it takes its data not from a relational database (as you have seen so far), but from an XML disk file named delivery.xml, stored in the XML- Datasubfolder of the PPQ site. The good news is that you can use a data source control to access this data, and then bind a data display control to this data source control to display the data — in much the same way as you did with a SqlDataSourcecontrol and the GridViewcontrol in previous examples.
The file delivery.xmllooks like this:
<?xml version=”1.0” encoding=”utf-8” ?> <ppq-delivery-areas>
<delivery-area id=”1” name=”Uptown” delivery-cost=”2.5” /> <delivery-area id=”2” name=”Downtown” delivery-cost=”3.5” /> <delivery-area id=”3” name=”Middletown” delivery-cost=”3” /> <delivery-area id=”4” name=”Out of town” delivery-cost=”5.5” />
<delivery-area id=”5” name=”Wrong side of the tracks” delivery-cost=”7.5” /> <delivery-area id=”6” name=”Out of State” delivery-cost=”15” />
</ppq-delivery-areas>
An XmlDataSourcecontrol can read this file and expose it as a rowset to which a GridViewcontrol
(and other list controls) can be data-bound. However, life is not always as simple as this, as you will see in this example.
1.
Open the PPQ.masterpage in Design view, right-click on the ContentPlaceHoldercontrol, and select Add Content Page. Switch the new page to Designview, and save it as Delivery.aspx using the Save Default2.aspx As . . . option on the File menu. Now drag an XmlDataSource control from the Data section of the Toolbox onto the page, and select Configure Data Source from the XmlDataSource Tasks pane. Click the Browse...button next to the “Data file:” text box, and select the file delivery.xmlfrom the XML-Datasubfolder (see Figure 5-34).2.
Click OK, and then drag a GridViewcontrol from the Toolbox onto the page. In the GridView Tasks pane, select XmlDataSource1in the Choose Data Source drop-down list, and theGridViewshows the values of the attributes in each of the <delivery-area>elements. Apply
an Auto Format of your choice, and then select Edit Columns . . . in the GridView Tasks pane (see Figure 5-35).
Figure 5-35: Selecting Edit Columns . . . in the GridView Tasks pane
3.
Remove the first column (named id) by clicking on it in the Selected fields: list and clicking the button next to this list. Select the namecolumn and change the HeaderTextproperty to Delivery Area. Then select the delivery-costcolumn and change the HeaderTextproperty to just Cost. This final column contains a value for the delivery cost and should be displayed as a cur- rency amount, so enter the format string $ {0:F2}you used in previous examples for the4.
Now, run the page to see the results. You have values in the GridViewcontrol, but the Cost column is not formatted correctly (see Figure 5-37). This is because the values in the attributes of the XML file are text strings and not numeric types, as they are when you extract data from a database.Figure 5-37: Improperly formatted
Costcolumn
5.
Go back to Design view, select the GridViewcontrol, and open the GridView Tasks pane. Select Edit Columns . . . and, in the Fields dialog, select the Costcolumn in the Selected fields: list. Click the link to “Convert this field into a TemplateField” (see Figure 5-38), and then click OK.6.
Now switch to Source view and look at the code that VWD has created, shown in the following listing. As expected, it has added a TemplateFieldto the declaration of the GridViewcontrol, replacing the BoundFieldfor the Costcolumn. It uses the Bindstatement to bind the values in the XML attributes to the Labeland TextBoxcontrols (even though you cannot switch to edit mode against an XmlDataSourcecontrol). The format string you specified is there but has no effect on the string data in the attribute.<asp:TemplateField HeaderText=”Cost” SortExpression=”delivery-cost”> <ItemTemplate>
<asp:Label ID=”Label1” runat=”server”
Text=’<%# Bind(“delivery-cost”, “$ {0:F2}”) %>’> </asp:Label>
</ItemTemplate> <EditItemTemplate>
<asp:TextBox ID=”TextBox1” runat=”server” Text=’<%# Bind(“delivery-cost”) %>’> </asp:TextBox>
</EditItemTemplate> </asp:TemplateField>
7.
The only solution is to change the binding statement to one that does provide the output format you need. If you write a custom function in code (you will see more on this topic in subsequent chapters) that creates and returns the value you want to display, you can call this function from here using the following:Text=’<%# MyFunction(XPath(“@delivery-cost”)) %>’>
This simply collects the value from the attribute that would have been bound to the Label control (using the XPathstatement and specifying the attribute named delivery-cost) and passes this value to your custom function. Whatever the function returns is displayed in the page. However, here is an even easier solution — you can include a single code statement that creates the value directly within the data-binding section (within the <%#and %>delimiters). The following statement creates the required result by specifying a dollar currency symbol and then applying the Formatmethod of the Stringclass to the result of parsing the value of the attribute into a number of type Double:
“$ “ & String.Format(“{0:F2}”, Double.Parse(XPath(“@delivery-cost”))) In your page (see Figure 5-39), delete the <EditTemplate>section and modify the
<ItemTemplate>section so that it looks like this:
<asp:TemplateField HeaderText=”Cost” SortExpression=”delivery-cost”> <ItemTemplate>
Figure 5-39: Deleting a section and modifying a section
8.
Now click “run” on the main toolbar, or press F5, to see the results. As you can see in Figure 5-40, the delivery costs are now properly displayed in currency format. This is yet another example of why it is often useful to understand and be able to use custom code when building your pages — and leaving it to VWD to do the hard work of generating the rest of the page!Figure 5-40: Delivery costs displaying in the proper format