I use C# preprocessor directives extensively while developing. I define them either directly in .cs
files or globally in the .csproj
:
<PropertyGroup>
<DefineConstants>fix_issue_001;fix_issue_002;</DefineConstants>
</PropertyGroup>
Or via command line as described here.
Then I use them to compartmentalize code:
#if fix_issue_001
// some new code
#else
// some old code
#endif
This helps me track changes, though I acknowledge it’s not the most readable or canonical approach. Version control and branching would be better, but we’re constrained to SVN and Visual Studio.
Now I want to extend this pattern to WPF XAML files. Since preprocessor directives aren’t available in XML, I’m looking at using XSLT to achieve similar functionality.
For example, I’d like to have something like this in my XAML:
<StackPanel>
<!-- fix_issue_001:true -->
<Button Content="Original version" Click="Button_Click" />
<!-- end fix_issue_001:true -->
<!-- fix_issue_001:false -->
<Button Content="New version" Background="LightGreen" Click="Button_Click" />
<!-- end fix_issue_001:false -->
</StackPanel>
The goal is to have XSLT transform this at build time, including/excluding sections based on whether fix_issue_001
is defined, just like #if/#else
works in C#.
Requirements:
- Maintain Visual Studio’s XAML designer functionality
- Minimize changes to existing code
- Prefer solutions using
.csproj
/.sln
and/or other configurations so it works seamlessly inside Visual Studio - Command line (batch/PowerShell) solutions are acceptable if necessary (e.g., using
xsltproc
or Saxon-HE)
Is this possible? How would you implement it?
P.S. Posted a new question here.
2
Answers
Its neither elegant nor exactly what you asked for but maybe you can go this direction:
alternativley you could create a converter that accepts a Name and a value as ConverterParameter and then checks the define and hides controls accordingly.
The way we do this is to add attributes to the elements.
I’ve put the attributes in a namespace here to distinguish them, but that’s your choice.
The XSLT code to retain some elements and remove others is then trivial.
For example, assuming the semantics are "if ‘fix_issue_010’ is present in the supplied options then drop all elements with v:fix_issue_010=false", then you might use a stylesheet like this:
The
xsl:mode
says copy everything by default; the firstxsl:template
says drop elements having an attribute in thev
namespace whose local name equals one of the supplied options and whose value is ‘false’; the secondxsl:template
says drop all attributes in thev
namespace.That might not be exactly the rules you want to apply, of course.