Archive for the ‘Programming’ Category.

NHibernate 2.1 and Unit Testing with MSTest Using MSBuild

I have a MSBuild script that Cruise Control is using to do it’s build and run the unit tests. After updating to NHibernate 2.1 and using NHibernate.ByteCode.LinFu for the ProxyFactoryFactory, the unit tests started failing in the build script, but not in Visual Studio.

I checked the references of my test project, and NHibernate.ByteCode.LinFu.dll was referenced, but the assembly wasn’t being copied into the test folder when ran with the script. I opened the test assembly up with ildasm.exe and checked the manifest and the LinFu assembly wasn’t in there. It was being references in the project, but apparently since there is not code actually using the assembly, the reference isn’t built into the manifest.

The way I fixed this is, in the unit test class I added a deployment item for the assembly that I wanted copied.

[DeploymentItem( @"..\References\NHibernate\NHibernate.ByteCode.LinFu.dll" )]
view raw File1.cs This Gist brought to you by GitHub.

This fixed the failing unit test. Life is good again.

How Safe is the Using Block?

I’m sure there are a lot of people out there who think of the using block as their security blanket. You can just wrap anything that has a close or dispose method on it in a using block, and everything is handled the way it should be, and automagically. Well, this isn’t always the case.

While doing some WCF work using the System.Component.ClientBase<TChannel>, I was running into a few issues. I was creating client proxy classes that inherited from ClientBase<TChannel>, and when using these, I would just wrap them in a using block.

using( var proxy = new MyProxy() )
{
    // Do some work.
}
view raw File5.cs This Gist brought to you by GitHub.

This seems like what you’re supposed to do, but in this case, it’s not. I ran across an article on MSDN “Avoiding Problems with the Using Statement” that explains why you can’t use the using block. Basically, the Close() method on the proxy can throw exceptions, such as a timeout, and if this occurs, you need to call Abort() instead.

Here is the correct way to handle a proxy:

var proxy = new MyProxy();
try
{
    // Do some work.
    proxy.Close();
}
catch( CommunicationException ex )
{
    proxy.Abort();
}
catch( TimeoutException ex )
{
    proxy.Abort();
}
catch( Exception ex )
{
    proxy.Abort();
    throw;
}
view raw File2.cs This Gist brought to you by GitHub.

After doing this a couple times, it gets pretty repetitive. I ended up creating a base proxy class and implementing IDisposable.

public abstract class ProxyBase<TChannel> : ClientBase<TChannel>, IDisposable where TChannel : class
{
protected void CheckDisposed()
{
if( disposed )
{
throw new ObjectDisposedException( GetType().Name );
}
}

public void Dispose()
{
Dispose( true );
GC.SuppressFinalize( this );
}

protected virtual void Dispose( bool disposing )
{
if( !disposed )
{
if( disposing )
{
try
{
base.Close();
}
catch( CommunicationException ex )
{
base.Abort();
}
catch( TimeoutException ex )
{
base.Abort();
}
catch( Exception ex )
{
base.Abort();
throw;
}
}

disposed = true;
}
}
}
view raw File3.cs This Gist brought to you by GitHub.

Now we can wrap our proxy in a using block again, and we get our security blanket back.

Changing Color Tint with C#

I’m currently doing a web application that has some branding. I’m doing a bunch of charts on metrics and there are specific color combinations that are used with charts. Each combination, or theme, has 3 main colors and 1 tint of that color, so 6 total. If you need more colors, you can do a tint percentage of the original color. Doing this in .NET wasn’t trivial and there isn’t a whole lot of information on the net about this.

First off, what does tinting mean? Basically, if you have red and want to tint it 10% lighter, you would add 10% of white to the red.

How this is done in .NET is by taking the System.Drawing.Color and converting it’s RGB values to HSL values. You then can bump the lighting up or down a certain percent. After it’s converted back into RGB color values it will be a tint of the original color.

Converting RGB to HSL:

This is simple in .NET. The color object has 3 methods for this: GetHue(), GetSaturation(), and GetBrightness(). But wait a second here, are brightness and lighting the same thing? No, they are not. Wikipedia has a good description on the difference http://en.wikipedia.org/wiki/HSL_and_HSV. So why are we not converting into HSB instead of HSL? Apparently .NET is actually giving back lighting and not brightness. Chris Jackson has a great post on this http://blogs.msdn.com/cjacks/archive/2006/04/12/575476.aspx. His conversion from HSL to RGB is also the one I’m using in this post. So we just assume that GetBrightness() is actually giving us the lighting that we need.

Converting HSL to RGB:

Here is the tricky part. Thanks to Chris Jackson for posting this code.

public static class ColorHelper
{
    /// <summary>
    /// Converts the HSL values to a Color.
    /// </summary>
    /// <param name="alpha">The alpha.</param>
    /// <param name="hue">The hue.</param>
    /// <param name="saturation">The saturation.</param>
    /// <param name="lighting">The lighting.</param>
    /// <returns></returns>
    public static Color FromHsl( int alpha, float hue, float saturation, float lighting )
    {
        if( 0 > alpha || 255 < alpha )
        {
            throw new ArgumentOutOfRangeException( "alpha" );
        }
        if( 0f > hue || 360f < hue )
        {
            throw new ArgumentOutOfRangeException( "hue" );
        }
        if( 0f > saturation || 1f < saturation )
        {
            throw new ArgumentOutOfRangeException( "saturation" );
        }
        if( 0f > lighting || 1f < lighting )
        {
            throw new ArgumentOutOfRangeException( "lighting" );
        }

        if( 0 == saturation )
        {
            return Color.FromArgb( alpha, Convert.ToInt32( lighting * 255 ), Convert.ToInt32( lighting * 255 ), Convert.ToInt32( lighting * 255 ) );
        }

        float fMax, fMid, fMin;
        int iSextant, iMax, iMid, iMin;

        if( 0.5 < lighting )
        {
            fMax = lighting - ( lighting * saturation ) + saturation;
            fMin = lighting + ( lighting * saturation ) - saturation;
        }
        else
        {
            fMax = lighting + ( lighting * saturation );
            fMin = lighting - ( lighting * saturation );
        }

        iSextant = (int)Math.Floor( hue / 60f );
        if( 300f <= hue )
        {
            hue -= 360f;
        }
        hue /= 60f;
        hue -= 2f * (float)Math.Floor( ( ( iSextant + 1f ) % 6f ) / 2f );
        if( 0 == iSextant % 2 )
        {
            fMid = hue * ( fMax - fMin ) + fMin;
        }
        else
        {
            fMid = fMin - hue * ( fMax - fMin );
        }

        iMax = Convert.ToInt32( fMax * 255 );
        iMid = Convert.ToInt32( fMid * 255 );
        iMin = Convert.ToInt32( fMin * 255 );

        switch( iSextant )
        {
            case 1:
                return Color.FromArgb( alpha, iMid, iMax, iMin );
            case 2:
                return Color.FromArgb( alpha, iMin, iMax, iMid );
            case 3:
                return Color.FromArgb( alpha, iMin, iMid, iMax );
            case 4:
                return Color.FromArgb( alpha, iMid, iMin, iMax );
            case 5:
                return Color.FromArgb( alpha, iMax, iMin, iMid );
            default:
                return Color.FromArgb( alpha, iMax, iMid, iMin );
        }
    }
}

Now that we can do the conversion, let’s create some extension methods on Color to do lightening and darkening.

public static class ColorExtensions
{
    /// <summary>
    /// Tints the color by the given percent.
    /// </summary>
    /// <param name="color">The color being tinted.</param>
    /// <param name="percent">The percent to tint. Ex: 0.1 will make the color 10% lighter.</param>
    /// <returns>The new tinted color.</returns>
    public static Color Lighten( this Color color, float percent )
    {
        var lighting = color.GetBrightness();
        lighting = lighting + lighting * percent;
        if( lighting > 1.0 )
        {
            lighting = 1;
        }
        else if( lighting <= 0 )
        {
            lighting = 0.1f;
        }
        var tintedColor = ColorHelper.FromHsl( color.A, color.GetHue(), color.GetSaturation(), lighting );

        return tintedColor;
    }

    /// <summary>
    /// Tints the color by the given percent.
    /// </summary>
    /// <param name="color">The color being tinted.</param>
    /// <param name="percent">The percent to tint. Ex: 0.1 will make the color 10% darker.</param>
    /// <returns>The new tinted color.</returns>
    public static Color Darken( this Color color, float percent )
    {
        var lighting = color.GetBrightness();
        lighting = lighting - lighting * percent;
        if( lighting > 1.0 )
        {
            lighting = 1;
        }
        else if( lighting <= 0 )
        {
            lighting = 0;
        }
        var tintedColor = ColorHelper.FromHsl( color.A, color.GetHue(), color.GetSaturation(), lighting );

        return tintedColor;
    }
}

Now this makes it easy to create a tint of any color. To use this in a web page, we can use the System.Drawing.ColorTranslator.ToHtml( Color c ) method to give us our html color.

NHibernate Mapping to System.Drawing.Color

In my POCO (Plain Old CLR Object) class, I had a property for FontColor that is of type System.Drawing.Color. I wanted this to map to an HTML string value in the database. i.e. #ffffff

Basically, I wanted to do a type conversion from #ffffff to System.Drawing.Color. At fist I didn’t realize that this sort of type conversion was built-in to NHibernate via the interface IUserType. I thought you had to use you new custom type in the POCO, but I found that you can just use the IUserType implementation to map to the native .NET type.

Here is how I did it…

First, create the custom type that implements IUserType. This will be used to do the type conversion from string to Color.

public class ColorUserType : IUserType
{
    public object Assemble( object cached, object owner )
    {
        return cached;
    }

    public object DeepCopy( object value )
    {
        return value;
    }

    public object Disassemble( object value )
    {
        return value;
    }

    public new bool Equals( object x, object y )
    {
        if(ReferenceEquals(x, y ) )
        {
            return true;
        }
        if( x == null || y == null )
        {
            return false;
        }
        return x.Equals( y );
    }

    public int GetHashCode( object x )
    {
        return x == null ? typeof( Color ).GetHashCode() + 473 : x.GetHashCode();
    }

    public bool IsMutable
    {
        get
        {
            return true;
        }
    }

    public object NullSafeGet( IDataReader rs, string[] names, object owner )
    {
        var obj = NHibernateUtil.String.NullSafeGet( rs, names[0] );
        if( obj == null )
        {
            return null;
        }
        return ColorTranslator.FromHtml( (string)obj );
    }

    public void NullSafeSet( IDbCommand cmd, object value, int index )
    {
        if( value == null )
        {
            ( (IDataParameter)cmd.Parameters[index] ).Value = DBNull.Value;
        }
        else
        {
            ( (IDataParameter)cmd.Parameters[index] ).Value = ColorTranslator.ToHtml( (Color)value );
        }
    }

    public object Replace( object original, object target, object owner )
    {
        return original;
    }

    public Type ReturnedType
    {
        get
        {
            return typeof( Color );
        }
    }

    public SqlType[] SqlTypes
    {
        get
        {
            return new[] { new SqlType( DbType.StringFixedLength ) };
        }
    }
}

Next, create the POCO.

public class MyClass
{
    public int Id { get; protected set; }
    public Color FontColor { get; set; }
}
view raw MyClass.cs This Gist brought to you by GitHub.

Next, create the mapping file. I’m using FluentNhibernate here.

public class MyClassMap : ClassMap<MyClass>
{
    public MyClassMap()
    {
        SetupMapping();
    }

    private void SetupMapping()
    {
        Id( m => m.Id );
        Map( m => m.FontColor ).CustomTypeIs<ColorUserType>();
    }
}
view raw MyClassMap.cs This Gist brought to you by GitHub.

Now when you get an instance of MyClass from NHibernate, the string color stored in the database will be converted to a System.Drawing.Color.

The New World of NHibernate

NHibernate has always been a great tool for data access but there are a couple things that have always bugged me; the mapping files and the non-type-safe querying. There are now some great tools out there that solve these problems.

Mapping files has always been a pain for me. It’s not the most intuitive thing and it’s really easy to miss-type something in the xml hbm files. I have started using Fluent Nhibernate to do my mapping files, which has made my life with NH a lot better. Not only do I no longer have to edit xml files, but now the mappings are type-safe. Fluent Nhibernate is a tool that I don’t think I could live without now.

POCO:

public class MyClass
{
    public virtual int? Id { get; private set; }
    public virtual string Name { get; set; }
    public virtual MyReference MyReference { get; set; }
    public virtual IList<MyReference> MyReferenceCollection { get; private set; }
}
view raw MyClass.cs This Gist brought to you by GitHub.

Mapping:

public class MyClassMap : ClassMap<MyClass>
{
    public MyClassMap()
    {
        Id( m => m.Id );
        Map( m => m.Name );
        References( m => m.MyReference );
        HasMany( m => m.MyReferenceCollection );
    }
}
view raw MyClassMap.cs This Gist brought to you by GitHub.

The other annoying thing is creating queries that aren’t type-safe, which makes doing re-factors a pain. You would think when using the Criteria language instead of HQL that it would be type-safe, but you still are using strings for the column names. I recently found a tool called NHLambdaExtensions which makes doing Criteria queries type-safe. This makes me sleep a little better at night.

// This:
session.CreateCriteria( typeof( MyClass ) ).Add( Expression.Eq( "Name", name ) );

// Becomes this:
session.CreateCriteria( typeof( MyClass ) ).Add<MyClass>( m => m.Name == name ).List();
view raw Criteria.cs This Gist brought to you by GitHub.

What about the Linq-To-Everything craze? I’m definitely a person that loves Linq and use it constantly, so naturally I’m wondering when a Linq-To-NHibernate provider will be coming out. Oren Eini had a simple implementation going but didn’t handle many of the complex scenarios (or so I’ve read, and I must say, he’s a coding machine). But don’t fear, Steve Strong has been employed to create a fully functional Linq-To-NHibernate provider. I’m excited to see it come to fruition and can’t wait to actually use it. You can keep up with the progress at Steve’s blog at http://blogs.imeta.co.uk/sstrong.

UPDATE:

[Fluent] NHibernate now comes with a Linq provider and I recommend using that over criteria.

Making a Custom Window Resizable in WPF

This is a continuation of my Creating a Custom Window in WPF post. If we create a custom window, we want the window to behave like a normal window. One of those things are making the window resizable.

To make the window resizable, we need something to grab on to. We can’t use the border, because we can’t specify a side or corner of the border, so we will need to create our own border that we can grab.

Let’s start by making the top/right/bottom/left sides. Since our corner has a radius of 10, we’ll set margins on the sides so they don’t overlap the corner. We also want to put a negative margin so that the sides will overlap the border. There are some events here that we’ll use later.

<aero:SystemDropShadowChrome CornerRadius="10" Margin="10">
    <Border BorderThickness="1" BorderBrush="Black" Background="White"
        Margin="0" CornerRadius="10">
        <Grid>
            <Border Height="40" Background="#01000000" VerticalAlignment="Top"
                    CornerRadius="10,10,0,0" MouseLeftButtonDown="DragWindow" />
            <Rectangle x:Name="ResizeN" Fill="Yellow" VerticalAlignment="Top"
                       Height="4" Margin="9,-2,9,0" MouseEnter="DisplayResizeCursor"
                       MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize" />
            <Rectangle x:Name="ResizeE" Fill="Yellow" HorizontalAlignment="Right"
                       Width="4" Margin="0,9,-2,9" MouseEnter="DisplayResizeCursor"
                       MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize" />
            <Rectangle x:Name="ResizeS" Fill="Yellow" VerticalAlignment="Bottom"
                       Height="4" Margin="9,0,9,-2" MouseEnter="DisplayResizeCursor"
                       MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize" />
            <Rectangle x:Name="ResizeW" Fill="Yellow" HorizontalAlignment="Left"
                       Width="4" Margin="-2,9,0,9" MouseEnter="DisplayResizeCursor"
                       MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize" />
        </Grid>
    </Border>
</aero:SystemDropShadowChrome>
view raw Example1.xml This Gist brought to you by GitHub.

Now we can create the corners with a radius of 10.

<Path x:Name="ResizeNW" VerticalAlignment="Top" HorizontalAlignment="Left"
      Stroke="Green" StrokeThickness="4" Margin="0" MouseEnter="DisplayResizeCursor"
           MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize">
    <Path.Data>
        <PathGeometry>
            <PathGeometry.Figures>
                <PathFigureCollection>
                    <PathFigure StartPoint="0,10">
                        <PathFigure.Segments>
                            <PathSegmentCollection>
                                <QuadraticBezierSegment Point1="0,0" Point2="10,0" />
                            </PathSegmentCollection>
                        </PathFigure.Segments>
                    </PathFigure>
                </PathFigureCollection>
            </PathGeometry.Figures>
        </PathGeometry>
    </Path.Data>
</Path>
<Path x:Name="ResizeNE" VerticalAlignment="Top" HorizontalAlignment="Right"
      Stroke="Green" StrokeThickness="4" Margin="0,0,-2,0" MouseEnter="DisplayResizeCursor"
           MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize">
    <Path.Data>
        <PathGeometry>
            <PathGeometry.Figures>
                <PathFigureCollection>
                    <PathFigure StartPoint="0,0">
                        <PathFigure.Segments>
                            <PathSegmentCollection>
                                <QuadraticBezierSegment Point1="10,0" Point2="10,10" />
                            </PathSegmentCollection>
                        </PathFigure.Segments>
                    </PathFigure>
                </PathFigureCollection>
            </PathGeometry.Figures>
        </PathGeometry>
    </Path.Data>
</Path>
<Path x:Name="ResizeSE" VerticalAlignment="Bottom" HorizontalAlignment="Right"
      Stroke="Green" StrokeThickness="4" Margin="0,0,-2,-2" MouseEnter="DisplayResizeCursor"
           MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize">
    <Path.Data>
        <PathGeometry>
            <PathGeometry.Figures>
                <PathFigureCollection>
                    <PathFigure StartPoint="10,0">
                        <PathFigure.Segments>
                            <PathSegmentCollection>
                                <QuadraticBezierSegment Point1="10,10" Point2="0,10" />
                            </PathSegmentCollection>
                        </PathFigure.Segments>
                    </PathFigure>
                </PathFigureCollection>
            </PathGeometry.Figures>
        </PathGeometry>
    </Path.Data>
</Path>
<Path x:Name="ResizeSW" VerticalAlignment="Bottom" HorizontalAlignment="Left"
      Stroke="Green" StrokeThickness="4" Margin="0,0,0,-2" MouseEnter="DisplayResizeCursor"
           MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize">
    <Path.Data>
        <PathGeometry>
            <PathGeometry.Figures>
                <PathFigureCollection>
                    <PathFigure StartPoint="0,0">
                        <PathFigure.Segments>
                            <PathSegmentCollection>
                                <QuadraticBezierSegment Point1="0,10" Point2="10,10" />
                            </PathSegmentCollection>
                        </PathFigure.Segments>
                    </PathFigure>
                </PathFigureCollection>
            </PathGeometry.Figures>
        </PathGeometry>
    </Path.Data>
</Path>
view raw Example2.xml This Gist brought to you by GitHub.

Now we need to make the corners and edges resizable. We also need to make the cursor change when it hovers the corners and edges. To do this, we implement the events I mentioned earlier.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Interop;
using System.Runtime.InteropServices;

namespace ResizableWindow
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private const int WM_SYSCOMMAND = 0x112;
        private HwndSource hwndSource;

        private enum ResizeDirection
        {
            Left = 61441,
            Right = 61442,
            Top = 61443,
            TopLeft = 61444,
            TopRight = 61445,
            Bottom = 61446,
            BottomLeft = 61447,
            BottomRight = 61448,
        }

[DllImport( "user32.dll", CharSet = CharSet.Auto )]
        private static extern IntPtr SendMessage( IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam );

        public Window1()
        {
            SourceInitialized += Window1_SourceInitialized;

            InitializeComponent();
        }

        private void Window1_SourceInitialized( object sender, EventArgs e )
        {
            hwndSource = PresentationSource.FromVisual( (Visual)sender ) as HwndSource;
        }

        private void ResizeWindow( ResizeDirection direction )
        {
            SendMessage( hwndSource.Handle, WM_SYSCOMMAND, (IntPtr)direction, IntPtr.Zero );
        }

        protected void ResetCursor( object sender, MouseEventArgs e )
        {
            if( Mouse.LeftButton != MouseButtonState.Pressed )
            {
                this.Cursor = Cursors.Arrow;
            }
        }

        protected void Resize( object sender, MouseButtonEventArgs e )
        {
            var clickedShape = sender as Shape;

            switch( clickedShape.Name )
            {
                case "ResizeN":
                    this.Cursor = Cursors.SizeNS;
                    ResizeWindow( ResizeDirection.Top );
                    break;
                case "ResizeE":
                    this.Cursor = Cursors.SizeWE;
                    ResizeWindow( ResizeDirection.Right );
                    break;
                case "ResizeS":
                    this.Cursor = Cursors.SizeNS;
                    ResizeWindow( ResizeDirection.Bottom );
                    break;
                case "ResizeW":
                    this.Cursor = Cursors.SizeWE;
                    ResizeWindow( ResizeDirection.Left );
                    break;
                case "ResizeNW":
                    this.Cursor = Cursors.SizeNWSE;
                    ResizeWindow( ResizeDirection.TopLeft );
                    break;
                case "ResizeNE":
                    this.Cursor = Cursors.SizeNESW;
                    ResizeWindow( ResizeDirection.TopRight );
                    break;
                case "ResizeSE":
                    this.Cursor = Cursors.SizeNWSE;
                    ResizeWindow( ResizeDirection.BottomRight );
                    break;
                case "ResizeSW":
                    this.Cursor = Cursors.SizeNESW;
                    ResizeWindow( ResizeDirection.BottomLeft );
                    break;
                default:
                    break;
            }
        }

        protected void DisplayResizeCursor( object sender, MouseEventArgs e )
        {
            var clickedShape = sender as Shape;

            switch( clickedShape.Name )
            {
                case "ResizeN":
                case "ResizeS":
                    this.Cursor = Cursors.SizeNS;
                    break;
                case "ResizeE":
                case "ResizeW":
                    this.Cursor = Cursors.SizeWE;
                    break;
                case "ResizeNW":
                case "ResizeSE":
                    this.Cursor = Cursors.SizeNWSE;
                    break;
                case "ResizeNE":
                case "ResizeSW":
                    this.Cursor = Cursors.SizeNESW;
                    break;
                default:
                    break;
            }
        }

        protected void DragWindow( object sender, MouseButtonEventArgs e )
        {
            DragMove();
        }
    }
}
view raw Example3.cs This Gist brought to you by GitHub.

Now the edges are resizable. We don’t want to keep the green and yellow coloring, so we can change all the colors to almost transparent by setting the colors to #01000000.

And now our window looks like normal again and is resizable.

Creating a Common Window in WPF

The is a continuation of my last post Creating a Custom Window in WPF. If you have a custom window that you’re using, you’re going to want all windows to look the same and you don’t want to have to copy the code into every window.

One way to do this is to create a ControlTemplate for the window. All you have to do is set Template=”{DynamicResource WindowTemplate}” on the window.

<ControlTemplate TargetType="Window" x:Key="WindowTemplate">
    <aero:SystemDropShadowCrome CornerRadius="10" Margin="10">
        <Border BorderThickness="1" BorderBrush="Black" Background="White"
                CornerRadius="10">
            <Border Height="40" Background="#01000000" VerticalAlignment="Top"
                    CornerRadius="10,10,0,0" MouseLeftButtonDown="DragWindow">
                <ContentPresenter />
            </Border>
        </Border>
    </aero:SystemDropShadowCrome>
</ControlTemplate>
view raw Example1.xml This Gist brought to you by GitHub.

There is a problem with this though. If you want multiple windows to use the template, you’ll need to put the template in a resource file and include it in the each window that you want to have the template. If you want to use any events, such as MouseLeftButtonDown, like in this example, you can’t put it in an external resource file.

The way I found to fix this, is to create an abstract base class that creates the code. You can then wire the events up right in the base class. They key to doing this is to create a ContentPresenter control, and set the window’s content to the content of the presenter. This makes it so that any code that is put in the window will show up in the presenter.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.Windows.Themes;

namespace CommonWindow
{
    public abstract class WindowBase : Window
    {
        public WindowBase()
        {
            Initialized += WindowBaseInitialized;
        }

        private void WindowBaseInitialized( object sender, System.EventArgs e )
        {
            SetResourceReference( Window.StyleProperty, "Window" );
            ResourceDictionary resource = new ResourceDictionary();
            resource.Source = new Uri( "pack://application:,,,/WindowResource.xaml" );
            this.Resources.MergedDictionaries.Add( resource );

            SystemDropShadowChrome dropShadow = new SystemDropShadowChrome();
            dropShadow.SetResourceReference( Control.StyleProperty, "WindowShadow" );

            Border windowBorder = new Border();
            windowBorder.SetResourceReference( Control.StyleProperty, "WindowBorder" );
            dropShadow.Child = windowBorder;

            Grid grid = new Grid();
            grid.RowDefinitions.Add( new RowDefinition() { Height = new GridLength( 40.0 ) } );
            grid.RowDefinitions.Add( new RowDefinition() );
            windowBorder.Child = grid;

            Border headerBorder = new Border();
            headerBorder.SetResourceReference( Control.StyleProperty, "HeaderBorder" );
            headerBorder.MouseLeftButtonDown += DragWindow;
            grid.Children.Add( headerBorder );
            Grid.SetRow( headerBorder, 0 );

            ContentPresenter contentPresenter = new ContentPresenter();
            contentPresenter.Content = this.Content;
            grid.Children.Add( contentPresenter );
            Grid.SetRow( contentPresenter, 1 );

            this.Content = dropShadow;
        }

        private void DragWindow( object sender, MouseButtonEventArgs e )
        {
            DragMove();
        }
    }
}
view raw Example2.cs This Gist brought to you by GitHub.

We should put all the styling in a resource, which is the first thing included when creating the base code.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:aero="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">

    <Style TargetType="Window" x:Key="Window">
        <Setter Property="AllowsTransparency" Value="True" />
        <Setter Property="WindowStyle" Value="None" />
        <Setter Property="Background" Value="Transparent" />
    </Style>

    <Style TargetType="aero:SystemDropShadowChrome" x:Key="WindowShadow">
        <Setter Property="CornerRadius" Value="10" />
        <Setter Property="Margin" Value="10" />
    </Style>

    <Style TargetType="Border" x:Key="WindowBorder">
        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="BorderBrush" Value="Black" />
        <Setter Property="Background" Value="White" />
        <Setter Property="CornerRadius" Value="10" />
    </Style>

    <Style TargetType="Border" x:Key="HeaderBorder">
        <Setter Property="Grid.Row" Value="0" />
        <Setter Property="Background" Value="#01000000" />
        <Setter Property="VerticalAlignment" Value="Stretch" />
        <Setter Property="HorizontalAlignment" Value="Stretch" />
        <Setter Property="CornerRadius" Value="10,10,0,0" />
    </Style>

</ResourceDictionary>
view raw Example3.xml This Gist brought to you by GitHub.

All that we need to do now to get a window to have our common look is inherit from the base class. All the styling, resources and controls will automatically be there.

namespace CommonWindow
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : WindowBase
    {
        public Window1()
        {
            InitializeComponent();
        }
    }
}
view raw Example4.cs This Gist brought to you by GitHub.
<local:WindowBase x:Class="CommonWindow.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:CommonWindow"
    Title="Window1" Height="300" Width="300">

    <Label Content="blah" />
</local:WindowBase>
view raw Example5.xml This Gist brought to you by GitHub.

Now anything we put in our window will show up in our custom window, like our “blah” label.

So all the base controls are coded but we can still abstract most of it out to xaml in resource files. Now we have a common window that we can use and all we have to do is inherit from a base class.

Creating a Custom Window in WPF

For an app I’m working on I wanted to create a custom window look. Here is how I did it.

The default window looks like this:

<Window x:Class="CustomWindow.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:aero="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
    Title="Window1" Height="300" Width="300">
    <Grid>

    </Grid>
</Window>
view raw Example1.xml This Gist brought to you by GitHub.

To make a custom window, we need remove the default window, and make the window transparent. This will make it so there is no window that shows at all. We need to change the AllowsTransparency, WindowStyle and Background properties.

<Window x:Class="CustomWindow.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:aero="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
    Title="Window1" Height="300" Width="300"
    AllowsTransparency="True" WindowStyle="None" Background="Transparent">
    <Grid>

    </Grid>
</Window>
view raw Example2.xml This Gist brought to you by GitHub.

Now we need to start creating our own window. Lets add a border for the window.

<Window x:Class="CustomWindow.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:aero="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
    Title="Window1" Height="300" Width="300"
    AllowsTransparency="True" WindowStyle="None" Background="Transparent">

    <Border BorderThickness="1" BorderBrush="Black" Background="White"
        Margin="0" CornerRadius="10">
    </Border>

</Window>
view raw Example3.xml This Gist brought to you by GitHub.

Now that we have our own window design, we should make a draggable area at the top. I made the background black so you could see the draggable area. We need the corner radius to be the same as the window for the top and left and top right so that it doesn’t go over the window. On the border’s MouseLeftButtonDown event, we want to allow the window to be draggable. To make the draggable area be invisible, set the color to #01000000. This will make the border almost completely transparent. It will look 100% transparent, but you will still be able to click on it.

<Window x:Class="CustomWindow.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:aero="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
    Title="Window1" Height="300" Width="300"
    AllowsTransparency="True" WindowStyle="None" Background="Transparent">

    <Border BorderThickness="1" BorderBrush="Black" Background="White"
        Margin="0" CornerRadius="10">
        <Border Height="40" Background="#01000000" VerticalAlignment="Top"
            CornerRadius="10,10,0,0" MouseLeftButtonDown="DragWindow"/>
    </Border>

</Window>
view raw Example4.xml This Gist brought to you by GitHub.
using System.Windows;
using System.Windows.Input;

namespace CustomWindow
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        protected void DragWindow( object sender, MouseButtonEventArgs e )
        {
            DragMove();
        }
    }
}
view raw Example5.cs This Gist brought to you by GitHub.

Now lets add a drop shadow to the window. We need to add the PresentationFramework.Aero assembly. We can then use the SystemDropShadowChrome control.

<Window x:Class="CustomWindow.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:aero="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
    Title="Window1" Height="300" Width="300"
    AllowsTransparency="True" WindowStyle="None" Background="Transparent">

    <aero:SystemDropShadowChrome CornerRadius="10" Margin="10">
        <Border BorderThickness="1" BorderBrush="Black" Background="White"
            Margin="0" CornerRadius="10">
            <Border Height="40" Background="#01000000" VerticalAlignment="Top"
                CornerRadius="10,10,0,0" MouseLeftButtonDown="DragWindow"/>
        </Border>
    </aero:SystemDropShadowChrome>

</Window>
view raw Example6.xml This Gist brought to you by GitHub.

Now we have a customized window. If you want to add a maximize, minimize, and close button, you can add them to the draggable header border and hook the events up. To max/min the window, set the WindowState = WindowState.Maximized, WindowState.Minimized or WindowState.Normal. To close the window just call Close().

Visual Studio 2008 FxCop Errors

I converted a 2005 solution over to 2008 and hit build. I received this error:

MSBUILD : error : Invalid settings passed to CodeAnalysis task

I figured out that the problem was Visual Studio was calling FxCop from the “Visual Studio 8″ directory instead of “Visual Studio 9.0″. To fix this I had to change an environment variable called “FXCOPDIR” to point to the 2008 instance of Visual Studio.

I’m not sure why the install of 2008 didn’t do this. Oh well.