UGTS Document #32 - Last Modified: 8/29/2015 3:23 PM
WPF Windows and Class Libraries
If you try to define a WPF Window class in a class library project in Visual Studio 2010, you will immediately be faced with three hurdles:
- No Template - You can't just right click a folder in your class library project and Add, New Item..., WPF (Window), because this
template is not available in a class library project. There are two ways around this - either create the WPF Window in a non class library
project and then drag it into the class library, or hand-code a new .xaml / .xaml.vb file pair in the class library.
- ApplicationDefinition Build Action - As soon move your WPF window class to a class library, the compiler error 'Library Project File cannot specify
ApplicationDefinition element' will be shown. You are getting this error because when you moved the XAML file to your class library, its Build Action
was changed from 'Page' to 'ApplicationDefinition'. This happens because whenever you create a class that isn't typically found in a class library
(such as a WPF Window), Visual Studio changes it to Build Action = 'ApplicationDefinition'.
The error you are getting here speaks correctly - class library files cannot have elements with a build action of ApplicationDefinition, because this
Build Action only has meaning for executables. The solution is to get properties on the XAML file, and change the Build Action back to 'Page', and
recompile. As soon as you change it back to 'Page', this will fix a number of other errors as well, because now the compiler will treat the XAML file
as a page definition for your code-behind file, and the references to the control elements will be recognized, and the class will inherit properly
from System.Windows.Window. However, you may also need to add a line to the
top of the xaml.vb file: 'Imports System.Windows' so that the Windows namespace
is found properly.
- Application.xaml Conflicts - After the first two fixes, you may get a compiler error Class 'Application' must implement 'Sub InitializeComponent()'
for interface 'System.Windows.Markup.IComponentConnector'. You can manually fix this once by browsing to the error and modifying the signature on the
'Sub InitializeComponent' method to add 'Implements IComponentConnector.InitializeComponent', but this is not a permanent fix because this Application.g.i.vb file
is an auto-generated code file which is re-created every time you build, which effectively prevents you from building a working assembly.
The fix for this is to decide what you want your application's entry point to be - do you want it to be the Application.xaml application framework,
or your own custom entry point (which gives you greater flexibility at launch)? If you're going to use your own entry point, then just delete the Application.xaml
file from your project and set the project's Application Startup Object to your custom entry point. Or, remove any conflicting entry points, and point to
the Startup Object to 'Sub Main' and 'Enable application framework'.
Once these three issues are dealt with, you should be able to compile and use the WPF Window from your class library.