Another reader question of general interest.I received the following question in email the other day:
I have a question regarding the c# conditional attribute. Is it possible to set the condition using web.config or app.config files? I am trying to set a condition in the web.config/app.config and compile a method if my condition is not defined in the web.config/app.config.
I thought it would be of general interest, so I’ll post the answer here:
The argument to the conditional attribute is evaluated at compile time, not at runtime. That means you cannot set the condition in your app.config or web.config files.
To achieve the behavior you want, you can use the TraceSwitch class. I discuss this in Item 36 of Effective C#. The example I give are not exactly the same as the conditional attribute, but you can achieve the effect of the ConditionalAttribute by checking the value of the switch inside the method, and proceeding only if the desired value is present.
Reader question on different options to align text using GDI+I received a GDI+ question on text alignment recently. He was concerned because there were only three options to align text: Near, Center, and Far.
It’s actually a bit deeper than that, but the .NET framework designers tried to make it as simply as possible in most cases, yet still give you all the possibilities to format and align text in all the ways that you want.
There are three different parameters that control text alignment in GDI+ (and, therefore .NET programs): Text Alignment, Line Alignment, and whether to align the text to a point or inside a bounding rectangle. The end result gives you 18 different possibilities.
This image shows a short bit of text with all 9 different alignment combinations around 9 different points.

The alignment point is at the intersection of the blue lines. The code is below:
privatevoid DrawPointText( Graphics graphics)
{
float xDelta = (float )this.ClientRectangle.Size.Width / 4f;
float yDelta = ( float ) this.ClientRectangle.Size.Height / 4f;
StringFormat f = new StringFormat();
graphics.DrawLine( Pens.Blue, xDelta, 0f, xDelta,
(float )ClientRectangle.Height );
graphics.DrawLine( Pens.Blue, xDelta * 2f, 0f, xDelta * 2f,
(float )ClientRectangle.Height );
graphics.DrawLine( Pens.Blue, xDelta * 3f, 0f, xDelta * 3f,
(float )ClientRectangle.Height );
graphics.DrawLine( Pens.Blue, 0, yDelta,
( float ) ClientRectangle.Width, yDelta );
graphics.DrawLine( Pens.Blue, 0, yDelta* 2f,
( float ) ClientRectangle.Width, yDelta * 2f);
graphics.DrawLine( Pens.Blue, 0, yDelta * 3f,
( float ) ClientRectangle.Width, yDelta * 3f);
f.Alignment = StringAlignment.Near;
f.LineAlignment = StringAlignment.Near;
graphics.DrawString("Near, Near Line", this.Font, Brushes.Black,
xDelta*3, yDelta, f );
f.LineAlignment = StringAlignment.Center;
graphics.DrawString("Near, Center Line", this.Font, Brushes.Black,
xDelta*3, yDelta*2, f );
f.LineAlignment = StringAlignment.Far;
graphics.DrawString("Near, Far Line", this.Font, Brushes.Black,
xDelta*3, yDelta*3, f );
f.Alignment = StringAlignment.Center;
f.LineAlignment = StringAlignment.Near;
graphics.DrawString("Center, Near Line", this.Font, Brushes.Black,
xDelta*2, yDelta, f );
f.LineAlignment = StringAlignment.Center;
graphics.DrawString("Center, Center Line", this.Font, Brushes.Black,
xDelta*2, yDelta*2f, f );
f.LineAlignment = StringAlignment.Far;
graphics.DrawString("Center, Far Line", this.Font, Brushes.Black,
xDelta*2, yDelta*3f, f );
f.Alignment = StringAlignment.Far;
f.LineAlignment = StringAlignment.Near;
graphics.DrawString("Far, Near Line", this.Font, Brushes.Black,
xDelta, yDelta, f );
f.LineAlignment = StringAlignment.Center;
graphics.DrawString("Far, Center Line", this.Font, Brushes.Black,
xDelta, yDelta*2f, f );
f.LineAlignment = StringAlignment.Far;
graphics.DrawString("Far, Far Line", this.Font, Brushes.Black,
xDelta, yDelta*3f, f );
}
The other nine combinations are created by aligning the text inside a bounding rectangle. This image shows the same text aligned inside the window rectangle, using all 9 alignment combinations.

The code is below:
privatevoid DrawRectText( Graphics graphics)
{
StringFormat f = new StringFormat();
RectangleF bounds = new RectangleF(
( float ) this.ClientRectangle.X,
( float ) this.ClientRectangle.Y,
( float ) this.ClientRectangle.Width,
( float ) this.ClientRectangle.Height );
f.Alignment = StringAlignment.Near;
f.LineAlignment = StringAlignment.Near;
graphics.DrawString( "Near, Near", this.Font, Brushes.Black,
bounds, f );
f.Alignment = StringAlignment.Center;
f.LineAlignment = StringAlignment.Near;
graphics.DrawString( "Center, Near", this.Font, Brushes.Black,
bounds, f );
f.Alignment = StringAlignment.Far;
f.LineAlignment = StringAlignment.Near;
graphics.DrawString( "Far, Near", this.Font, Brushes.Black,
bounds, f );
f.Alignment = StringAlignment.Near;
f.LineAlignment = StringAlignment.Center;
graphics.DrawString( "Near, Center", this.Font, Brushes.Black,
bounds, f );
f.Alignment = StringAlignment.Center;
f.LineAlignment = StringAlignment.Center;
graphics.DrawString( "Center, Center", this.Font, Brushes.Black,
bounds, f );
f.Alignment = StringAlignment.Far;
f.LineAlignment = StringAlignment.Center;
graphics.DrawString( "Center, Center", this.Font, Brushes.Black,
bounds, f );
f.Alignment = StringAlignment.Near;
f.LineAlignment = StringAlignment.Far;
graphics.DrawString( "Near, Far", this.Font, Brushes.Black,
bounds, f );
f.Alignment = StringAlignment.Center;
f.LineAlignment = StringAlignment.Far;
graphics.DrawString( "Center, Far", this.Font, Brushes.Black,
bounds, f );
f.Alignment = StringAlignment.Far;
f.LineAlignment = StringAlignment.Far;
graphics.DrawString( "Far, Far", this.Font, Brushes.Black,
bounds, f );
}
By picking the right alignment, line alignment, and whether you align to a point, or to a bounding rect, you do have all the control you want to place text exactly where it should go. The simplicity of the API can make it easy to ignore that these features exist, but with a bit of digging, you’ll find them.
Josh Holmes, our newest partner is now a Microsoft C# MVPJosh Holmes received a much-deserved MVP award recently. I can’t think of anyone more deserving, based on all he does to help developers in our area do more with .NET. I’m sure he’ll retain this honor for many years to come.
And, for those of you that know both of us, you get the inside joke that he’s a C# MVP. Of the two of us, I’ve got much more of a semi-colon addition than he does.
I’m proud that he’s part of our organization.
Josh's announcementWhat he has to say about the award
Josh's Blog A great resource for .NET developers