Code-Behind

In a .NET MAUI application, XAML (Extensible Application Markup Language) is commonly used to define the visual components of a page and works together with a C# class code-behind file. The code-behind class provides code support for events and can access elements define in the XAML markup. This sample illustrates a simple Product Detail Form using just XAML and a C# Code-Behind class. This sample loads data from our model and uses it to initialize our user interface. It allows you to enter data and click on the Save button to save the data back to the model.

Example

XAML Code-Behind from History

I think this sample is best understood from a history point of view. Well, .NET 1.0 was introduced in 2002 and during that time, WinForms (Windows Forms) was introduced together as the desktop UI technology together. To develop an application with graphical user interfaces, WinForms is all that you need to care about. Life was much simpler then. Many line of business applications using Windows Forms still exist today.

In 2006, WPF (Windows Presentation Foundation) was released as an alternative to WinForms. WPF uses XAML (Extensible MArkup Language), which is a language based on XML, to declare the user interface elements. In a WPF application, we use a .xaml file to declare the user interface and a code-behind file to describe the logic. This innovation improves on the separation of user interface and business logic issue prevalent in the development industry.

XAML was later adopted by Universal Windows Platform (UWP), which is what you need to develop an app for Windows Store (or Microsoft Store today). As of today, UWP further evolved to Windows App SDK and Xamarin (now .NET MAUI) also adopted XAML.

In the XAML code below, a Grid element is used to declare rows of fields consisting of a Title, Product Image, Product Name, Product Price, Product Description, and others.


        <ScrollView>
            <Grid Margin="25">
                <Grid.RowDefinitions>
                    <RowDefinition Height="50"></RowDefinition>
                    <RowDefinition Height="200"></RowDefinition>
                    <RowDefinition Height="50"></RowDefinition>
                    <RowDefinition Height="50"></RowDefinition>
                    <RowDefinition Height="100"></RowDefinition>
                    <RowDefinition Height="50"></RowDefinition>
                    <RowDefinition Height="50"></RowDefinition>
                    <RowDefinition Height="*"></RowDefinition>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width=".3*"></ColumnDefinition>
                    <ColumnDefinition Width=".7*"></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <Label x:Name="TitleLabel"
                    Text="Edit Product"
                    Grid.Row="0"
                    Grid.Column="0"
                    Grid.ColumnSpan="2"
                    FontSize="Large"></Label>
                <Image x:Name="ProductImage"
                    Grid.Column="0"
                    Grid.Row="1"
                    Grid.ColumnSpan="2"
                    Margin="10"
                    WidthRequest="200"
                    HeightRequest="200"
                    VerticalOptions="Center"></Image>
                <Label Text="Product name"
                    Grid.Row="2"
                    Grid.Column="0"
                    FontSize="Small"
                    VerticalOptions="Center"></Label>
                <Entry x:Name="ProductName"
                    Grid.Row="2"
                    Grid.Column="1"
                    VerticalOptions="Center"></Entry>
                <Label Text="Price"
                    Grid.Row="3"
                    Grid.Column="0"
                    FontSize="Small"
                    VerticalOptions="Center"></Label>
                <Entry x:Name="ProductPrice" 
                    Grid.Row="3"
                    Grid.Column="1"
                    FontSize="Small"
                    HorizontalOptions="FillAndExpand"
                    VerticalOptions="Center"></Entry>
                <Label
                    Text="Description"
                    Grid.Row="4"
                    Grid.Column="0"
                    FontSize="Small"></Label>
                <Editor x:Name="ProductDescription"
                    Grid.Row="4"
                    Grid.Column="1"
                    FontSize="Small"
                    HorizontalOptions="FillAndExpand"
                    VerticalOptions="Center"></Editor>
                <Label Text="Offer End Date"
                    Grid.Row="5"
                    Grid.Column="0"
                    FontSize="Small"
                    VerticalOptions="Center"></Label>
                <DatePicker x:Name="ProductOfferEndDate" 
                    Grid.Row="5"
                    Grid.Column="1"
                    VerticalOptions="Center"></DatePicker>			
                <Button x:Name="SaveProductButton"
                    Clicked="SaveProductButton_OnClicked"
                    Text="Save Product"
                    Grid.Row="6"
                    Grid.Column="0"
                    Grid.ColumnSpan="2"></Button>
            </Grid>
        </ScrollView>
            

Besides declaring how our user interface looks like in XAML. We need to load data from the model, enables changes to the data through the user interface, and validate the data when the Save button is clicked. Using Code Behind, there is a natural tendency to structure our code as below.

The constructor provides the code to initialize the user interface elements defined in XAML with the Product model attributes.

The SaveProductButton_OnClicked method performs the saving of the properties in the XAML markup elements back to the model.

.NET MAUI provides Data Binding to ease the above process. You basically just need to bind the user interface elements with your model and data binding will automatically make sure the data in the user interface and your model is in sync.


        public partial class MainPage : ContentPage
        {
            public Product MyProduct { get; set; }
            public MainPage()
            {
                InitializeComponent();
        
                MyProduct = new Product
                {
                    Id = 1,
                    Description = "Apple, Malus domestica, is one of the most widely cultivated tree fruits with a fleshy and edible surrounding tissue.",
                    ImageUrl = "https://mauiman.dev/mauishopimages/red-apple-isolated.jpg",
                    OfferEndDate = new DateTime(2025, 2, 10),
                    ProductName = "Apple",
                    Price = 2.80
                };
        
                ProductImage.Source = MyProduct.ImageUrl;
                ProductName.Text = MyProduct.ProductName;
                ProductPrice.Text = MyProduct.Price.ToString();
                ProductDescription.Text = MyProduct.Description;
                ProductOfferEndDate.Date = MyProduct.OfferEndDate;
        
            }
        
            private async void SaveProductButton_OnClicked(object sender, EventArgs e)
            {
        
                MyProduct.ImageUrl = ProductImage.Source.ToString();		 
                MyProduct.ProductName = ProductName.Text;
                MyProduct.Price = double.Parse(ProductPrice.Text);
                MyProduct.Description = ProductDescription.Text;
                MyProduct.OfferEndDate = ProductOfferEndDate.Date;
        
                await DisplayAlert("Success", "Product saved", "Done");
            }
        }                                    
                

The model class is shown below.


        public class Product 
        {
            private int id;
            private string productName;
            private string description;
            private double price;
            private string imageUrl;
            private DateTime offerEndDate;
    
            public int Id
            {
                get => id;
                set
                {
                    id = value; 
                }
            }
    
            public string ProductName
            {
                get => productName;
                set
                {
                    productName = value;
                }
            }
    
            public string Description
            {
                get => description;
                set
                {
                    description = value;
                }
            }
    
            public double Price
            {
                get => price;
                set
                {
                    price = value;
                }
            }
    
            public string ImageUrl
            {
                get => imageUrl;
                set
                {
                    imageUrl = value; 
                }
            }
    
            public DateTime OfferEndDate
            {
                get => offerEndDate;
                set
                {
                    offerEndDate = value; 
                }
            }
    
        }
        

Download

.NET MAUI