Click here to Skip to main content
Click here to Skip to main content

How to embed a C# code into an XAML file

, 10 Oct 2009
Rate this:
Please Sign up or sign in to vote.
A simple tutorial on how to embed a C# code into an XAML file

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[<span class="code-SummaryComment">

            void ButtonOnClick(object sender, RoutedEventArgs args)
            {
                Button btn = sender as Button;
                MessageBox.Show("The button labeled '" +
                                btn.Content +
                                "' has been clicked.","Information Message");
            }
            ]]></span>
        </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 {

    /// <span class="code-SummaryComment"><summary>
</span>    /// Window1
    /// <span class="code-SummaryComment"></summary>
</span>    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

        /// <span class="code-SummaryComment"><summary>
</span>        /// InitializeComponent
        /// <span class="code-SummaryComment"></summary>
</span>        [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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Volynsky Alex
Software Developer
Israel Israel
Mr.Volynsky Alex is a Software Engineer in a leading software company. Alex is skilled in many areas of computer science. He has over 13 years of experience in the design & development of applications using C/C++/STL, Qt, MFC, COM/ActiveX, DirectShow, JavaScript, VBScript, Tcl/Tk and of course - C#/.NET.
 
Overall, Alex is very easy to work with. He adapts to new systems and technology while performing complete problem definition research.
 
His hobbies include yacht racing, photography and reading in multiple genres.
He is also fascinated by attending computer meetings in general, loves traveling, and also takes pleasure in exercising and relaxing with friends.
 
Visit his C++ 11 blog

Comments and Discussions

 
GeneralMy vote of 5 Pinmembermk4you713-Jun-12 5:03 
GeneralRe: My vote of 5 PinmemberVolynsky Alex14-Jun-12 15:12 
GeneralMy vote of 5 PinmemberSteph_Iv28-May-12 10:41 
GeneralRe: My vote of 5 PinmemberVolynsky Alex14-Jun-12 15:12 
GeneralMy vote of 5 [modified] PinmemberEMogilevsky26-May-12 4:37 
GeneralRe: My vote of 5 PinmemberVolynsky Alex26-May-12 11:08 
GeneralRe: My vote of 5 PinmemberVolynsky Alex14-Jun-12 15:12 
GeneralMy vote of 5 PinmemberGerard Forestier24-May-12 22:24 
GeneralRe: My vote of 5 PinmemberVolynsky Alex26-May-12 11:09 
GeneralMy vote of 5 Pinmemberjfriedman20-May-12 8:43 
GeneralMy vote of 5 PinmemberY.Desros6-May-12 5:33 
JokeIt's really EXCELLENT! PinmemberWow77713-Oct-09 6:35 
GeneralRe: It's really EXCELLENT! PinmemberVolynsky Alex26-May-12 11:10 
Question[My vote of 2] Can I avoid compilation of code? PinmemberRakeshGunijan12-Oct-09 23:43 
GeneralGreat, but... PinmemberKarl Nicoll11-Oct-09 6:35 
GeneralTks Pinmembermartyn_mcfly10-Oct-09 23:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 10 Oct 2009
Article Copyright 2009 by Volynsky Alex
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid