Code-Behind and XAML in WPF

Code-behind is a term used to describe the code that is joined with markup-defined objects, when a XAML page is markup-compiled. This topic describes requirements for code-behind as well as an alternative inline code mechanism for code in XAML.

This topic contains the following sections:

Prerequisites

This topic assumes that you have read the XAML in WPF and have some basic knowledge of the CLR and object-oriented programming.

Code-Behind and the XAML Language

The XAML language includes language-level features that make it possible to associate code files with markup files, from the markup file side. Specifically, the XAML language defines the language features x:Class Directive, x:Subclass Directive, and x:ClassModifier Directive. Exactly how the code should be produced, and how to integrate markup and code, is not part of what the XAML language specifies. It is left up to frameworks such as WPF to determine how to integrate the code, how to use XAML in the application and programming models, and the build actions or other support that all this requires.

Code-behind, Event Handler, and Partial Class Requirements in WPF

  • The partial class must derive from the type that backs the root element.

  • Note that under the default behavior of the markup compile build actions, you can leave the derivation blank in the partial class definition on the code-behind side. The compiled result will assume the page root's backing type to be the basis for the partial class, even if it not specified. However, relying on this behavior is not a best practice.

  • The event handlers you write in the code-behind must be instance methods and cannot be static methods. These methods must be defined by the partial class within the CLR namespace identified by x:Class. You cannot qualify the name of an event handler to instruct a XAML processor to look for an event handler for event wiring in a different class scope.

  • The handler must match the delegate for the appropriate event in the backing type system.

  • For the Microsoft Visual Basic language specifically, you can use the language-specific Handles keyword to associate handlers with instances and events in the handler declaration, instead of attaching handlers with attributes in XAML. However, this technique does have some limitations because the Handles keyword cannot support all of the specific features of the WPF event system, such as certain routed event scenarios or attached events. For details, see Visual Basic and WPF Event Handling.

x:Code

x:Code is a directive element defined in XAML. An x:Code directive element can contain inline programming code. The code that is defined inline can interact with the XAML on the same page. The following example illustrates inline C# code. Notice that the code is inside the x:Code element and that the code must be surrounded by <CDATA[...]]> to escape the contents for XML, so that a XAML processor (interpreting either the XAML schema or the WPF schema) will not try to interpret the contents literally as XML.

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="MyNamespace.MyCanvasCodeInline"
>
  <Button Name="button1" Click="Clicked">Click Me!</Button>
  <x:Code><![CDATA[
    void Clicked(object sender, RoutedEventArgs e)
    {
        button1.Content = "Hello World";
    }
  ]]></x:Code>
</Page>

Inline Code Limitations

You should consider avoiding or limiting the use of inline code. In terms of architecture and coding philosophy, maintaining a separation between markup and code-behind keeps the designer and developer roles much more distinct. On a more technical level, the code that you write for inline code can be awkward to write, because you are always writing into the XAML generated partial class, and can only use the default XML namespace mappings. Because you cannot add using statements, you must fully qualify many of the API calls that you make. The default WPF mappings include most but not all CLR namespaces that are present in the WPF assemblies; you will have to fully qualify calls to types and members contained within the other CLR namespaces. You also cannot define anything beyond the partial class in the inline code, and all user code entities you reference must exist as a member or variable within the generated partial class. Other language specific programming features, such as macros or #ifdef against global variables or build variables, are also not available. For more information, see x:Code Intrinsic XAML Type.

See also