Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to Embed a C# Code into an XAML File

0.00/5 (No votes)
10 Oct 2009 1  
A simple tutorial on how to embed a C# code into an XAML file

Image 1

Introduction

This is a simple tutorial on how to embed C# code into an XAML file.

Windows-based WPF applications need to respond to user interface events in very specialized ways. Here is where XAML must be supplemented by real programming code. You can put the code in a CS's separate file or embed it directly in the XAML. In this article, I'll be showing the latter approach for the sake of simplicity. For you, it is entirely possible to embed C# code into an XAML file. It's not pretty, but it works. XAML actually supports “code inside” in addition to code behind (somewhat like in ASP.NET). This way can help if you do not wish to use CS's files (I don't know why).

This can be done with the Code keyword in the XAML language namespace, as explained below.

Using the Code

The first step is to create the WPF Application project in Visual C# and delete C# source code, i.e., files matching a specified CS extension.

Sample Image - maximum width is 600 pixels

The starting point is an XAML template, which is named App.xaml by default. You don't need to change the data of this file.

<Application x:Class="WpfApplicationWithoutCShFiles.App"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    StartupUri="Window1.xaml">
    <Application.Resources>

    </Application.Resources>
</Application>

NOTE: The Class attribute is used in XAML to create a class derived from the element. Visual Studio derives a custom class from Application class, with the name WpfApplicationWithoutCShFiles (WpfApplicationWithoutCShFiles is the name of the project, which is the same as the namespace where the class is defined, and App is the name that Visual Studio uses for the custom class that is derived from Application. The App.xaml file must have a Build Action of ApplicationDefinition, or nothing will work. If you want, you can change the class name to something more exciting.)

The Application tag not only creates a custom application class, but it also sets the StartupUri property to identify the XAML document that represents the main window. Notice that the StartupUri is the Window1.xaml file, which is this one:

<Window x:Class="WpfApplicationWithoutCShFiles.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="WPF Application Without CSharp Files"

    SizeToContent="WidthAndHeight"

    ResizeMode="CanMinimize"

    Height="300" Width="1000">

    <Grid Height="255" Width="930">

        <Button Margin="400,67,404,126"

                Click="ButtonOnClick">
            Press the Button
        </Button>

        <x:Code>
            <![CDATA[

            void ButtonOnClick(object sender, RoutedEventArgs args)
            {
                Button btn = sender as Button;
                MessageBox.Show("The button labeled '" +
                                btn.Content +
                                "' has been clicked.","Information Message");
            }
            ]]>
        </x:Code>
    </Grid>
</Window>

Embedded code requires using the x:Code element and a CDATA section within the x:Code element. The XML specification defines CDATA (which stands for "character data") as a section in an XML file for "blocks of text containing characters which would otherwise be recognized as markup," which is certainly the case for symbols used in C# and other programming languages.

The CDATA section always begins with the string "<![CDATA[" and always ends with the string "]]>". The <![CDATA[ ]]> tag is there to tell XML parsers to ignore anything that is contained within it. Without it, certain C# code might trip up the XML parsing.You must avoid using ]]> anywhere in the code, because that terminates the CDATA section!
For example, the following example may lead to the above problem:

m_Data = (arr_one[arr_two[3]]> 100) ? arr_one[arr_two[3]] : 0 ;

You can fix the problem by inserting a little white space somewhere within that inadvertent CDATA delimiter and all will be well.
This embedded code cannot define fields. The C#'s code can demand fully qualified namespace names if the generated code file does not automatically include using directives for those namespaces. Consider that the embedded code in file Window1.xaml should fully qualify classes in System.Reflection namespace.

When such an XAML file is compiled, the contents inside the x:Code element get plopped inside the partial class in the Window1.g.cs file (a C# source file with suffix .g.cs, where the g stands for generated.The code does get generated in the XAML compilation process , but it’s just some “glue code” similar to what had to be written to load and parse a loose XAML file at run-time).

using System;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Media.TextFormatting;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplicationWithoutCShFiles {

    /// <summary>
    /// Window1
    /// </summary>
    public partial class Window1 : System.Windows.Window, 
		System.Windows.Markup.IComponentConnector {

        private bool _contentLoaded;

        #line 17 "..\..\Window1.xaml"

            void ButtonOnClick(object sender, RoutedEventArgs args)
            {
                Button btn = sender as Button;
                MessageBox.Show("The button labeled '" +
                                btn.Content +
                                "' has been clicked.","Information Message");
            }

        #line default
        #line hidden

        /// <summary>
        /// InitializeComponent
        /// </summary>
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public void InitializeComponent() {
            if (_contentLoaded) {
                return;
            }
            _contentLoaded = true;
            System.Uri resourceLocater = new System.Uri("/WpfApplicationWithoutCShFiles;
			component/window1.xaml", System.UriKind.Relative);

            #line 1 "..\..\Window1.xaml"
            System.Windows.Application.LoadComponent(this, resourceLocater);

            #line default
            #line hidden
        }

        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [System.ComponentModel.EditorBrowsableAttribute
		(System.ComponentModel.EditorBrowsableState.Never)]
        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute
	    ("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
        void System.Windows.Markup.IComponentConnector.Connect
				(int connectionId, object target) {
            switch (connectionId)
            {
            case 1:

            #line 12 "..\..\Window1.xaml"
            ((System.Windows.Controls.Button)(target)).Click += 
		    new System.Windows.RoutedEventHandler(this.ButtonOnClick);

            #line default
            #line hidden
            return;
            }
            this._contentLoaded = true;
        }
    }
}

Although embedding C# code in an XAML file is sometimes convenient, nevertheless, the given technique should not be used too often, because it is not as elegant as a general-purpose solution. Besides making the division between UI and logic messier, loose XAML pages don't support it and Visual Studio doesn't show syntax coloring.

History

  • 09/04/08: Initial issue

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here