Visual Studio XML File Transformation Not Just For Web.Config

Being able to manage environment settings can be such a pain sometimes, especially when your doing it manually.  As of Visual Studio 2010 you are now able to associate environment specific settings based on a build configuration.  Imagine that you have a developement, QA, and production environment each having different database connections strings, log file paths, etc.  It would be nice to set this once and let the build determine the right output for you app.config file, no?  Well this feature is built in to web projects by default, but can be extended to any type of xml file.  There are a few steps to get it working but I will describe them below.  Most of these steps are based on this article XDT (web.config) Transforms in non-web projects which explains the general process and has an example attached.  There are a few items I will discuss which are not included in this article.

Prerequisites

  1. Visual Studio 2010 which has web projects (this conatins the TransfromXml build tasks).
  2. Create a folder %ProgramFiles (x86)%\MSBuild\Custom.  Download TransormFiles.targets and save to this directory with name TransformFiles.targets

Solution

In the solution below I will be use a WebForms project with additional xml files along with the default web.config file, a web.sitemap and a myfile.xml.  My project looks like the image below.

image

1.  Add the <Import> for TranformFiles.targets to you project file. 

Right click on you project and select “Unload project”, project should unload and be grayed out.  Right click again and select “Edit xxx.csproj” where xxx is your project name.  The project file will open and at the end of it put

<Import Project="$(MSBuildExtensionsPath)\Custom\TransformFiles.targets" />

image

2.  Update project file so that non app.config XML files’ (web.config in web project) are nested under the transformed file.  We’ll use the <DebendentUpon> element for each build file. For example a web.sitemap will have a web.release.sitemap if you are transforming you sitemap.

image

3.  Add the <TransormOnBuild> node to any XML file that is not a web.config file, this includes app.config files if you are not using a web project!  You only need to add this node to the files that have transformations applied.  For example, the web.sitemap will get this but the web.release.sitemap won’t.

image

4.  If you are using a web site project add the <CopyToOutputDirectory> to all XML files that will be transformed, other than the web.config file.  This will copy the transformed files to the bin folder of you build since it won’t copy the transformation to the same place as web.config file, unfortunately.  After the build you’ll have to manually copy these to their respective destinations.  Fortunately the output in the bin folder will have all the correct paths for these XML files.

image

imageProject view after steps 2-4

5.  Add the XML transform namespace http://schemas.microsoft.com/XML-Document-Transform to all you transform files.  If it’s a web project, remove the xmlns namespace in the root node of the web.sitemaps; if you don’t the transformation will not work on these files.  See Web.config Transformation Syntax for Web Application Project for the different transformation capabilities.

image

image 

6.  Build you code.  You should now see the transformation you applied.

ASP.NET CollapsiblePanelExtender Printing Content

The other day I was working with the ASP.NET Ajax toolkit’s CollapsiblePanelExtender and have the toughest time getting the content within the panel to print.  I found that there were 2 issues going on: 1)  you have to expand you panel before you print, and 2)  there is some CSS magic that you need to do to get all the content to show.  For the first issue, you have to expand all the panels before you print, which you can do using some JavaScript, unfortunately you can’t fire this when the user select File^Print.  The second issue I resolved using the CSS print media type, which I have an example of the principle here Printable Web Page

Expanding Collapsible Panels

This can be achieved by a little JavaScript.  In my situation the user’s wanted a toggle in the UI, I used a check box but a button can do the same thing.

1.  Create the UI toggle item that will fire JavaScript onclick event.

<input type=”checkbox” onclick=”toggleCollapsibleSections();” />

2.  Create the JavaScript that will expand/collapse the panels.  Note I’m using jQuery here to find the elements and that the ID of the collapsible panel is the client ID for the CollapsiblePanelExtender.  If you’re using .NET 4.0 you can set the extender’s ClientIDMode to Static otherwise you will have to either use CSS class to find extenders you want or spit our the X.ClientID where X is the extender control.

function toggleCollapsibleSections() {
    var isChecked = $("#toggleCheckbox").attr("checked");
    if (isChecked) 
        expandSections(true);
    else 
        expandSections(false);
}

function expandSections(doExpand) {
    if (doExpand) {
        $find("MyCollapsiblePanelExtenderClientID")._doOpen();
        // + all other section i want to open
    }
    else {
        $find("MyCollapsiblePanelExtenderClientID")._doClose();
        // + all other section i want to close
    }
}

Printing Collapsible Panel Content

This was a tough fix.  In a nut shell the CollapsiblePanelExtender applies a inline style “overflow” to the div that wraps you content.  This causes the printing to cut off the content within you section if the content is high enough.  The way to solve this is to define a overflow style for all div’s in you print media CSS file.  See Printable Web Page on details about defining and using print media CSS.  The CSS is listed below.  Notice the usage of the “!important” this will override any inline styles that the ajax toolkit has applied.

div { overflow: visible !important; }