Supporting WPF Binging Without the WindowsBase Library

WPF Bindings provide a powerful way to link your data with the user interface. But what can you do to keep your data classes independent from the WPF framework?

There are a couple of ways to support WPF binding. For none-UI classes the best option is to implement the INotifyPropertyChanged and INotifyCollectionChanged interfaces. Implementing them explicitly keeps the interface of your data classes clean and all the WPF functionality available only for those classes that support it.

private event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string name)
    if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(name));
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
    add { PropertyChanged += value; }
    remove { PropertyChanged -= value; }

Unfortunately in .NET 3.5 both the interfaces are a part of the WindowsBase WPF library, so it is not possible to support bindings without referencing to it. This also means all the assemblies that need to take advantage of your data classes need to reference the library.

It made me very happy to read in Jamie Rodriguez’s blog that in .NET 4.0 the notify interfaces have been type forwarded to System.dll! I could also confirm this using Visual Studio 2010 Beta 2. Hurray!

Ps. According to the Data Binding Performance article on MSDN, the notify interfaces provide a slightly better performance compared to using XXXChanged events.

Faster XML Serialization

A lot of run-time compilation is involved when the XmlSerializer is used. For better performance it is recommended to run sgen.exe to generate a serialization assembly to speed up the XML serialization. In a way, the idea behind SGen is the same as for NGen.

There is a Generate Serialization Assembly drop-down in the project settings in Visual Studio, but this covers only available Web service proxies. To have Visual Studio run SGen automatically for other types, you need to manually add the following lines to your project file:

<Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)"  Outputs="$(OutputPath)$(_SGenDllName)">         
    <SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(OutputPath)"  References="@(ReferencePath)" ShouldGenerateSerializer="true" UseProxyTypes="false" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="$(SGenToolPath)">
        <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />