Data binding is a fundamental concept in .NET MAUI that allows you to create a connection between your user interface (UI) elements and your data model. This connection enables automatic synchronization of data, meaning changes in the UI can update the data model, and changes in the data model can update the UI. This greatly simplifies the development of dynamic and interactive applications.
There are several ways to implement data binding in .NET MAUI:
In one-way binding, data flows from the source (your data model) to the target (your UI element). If the data in the source changes, the UI element is updated automatically. However, changes made to the UI element do not affect the source.
<Label Text="{Binding ProductName}" />
In this example, the `Text` property of the `Label` is bound to the `ProductName` property of the data context. If `ProductName` changes, the `Label` will update.
This is the inverse of one-way binding. Data flows from the target (UI element) to the source (data model). Changes in the UI element update the data model. This is commonly used for input controls like `Entry` or `Editor` where user input should update the underlying data.
<Entry Text="{Binding CustomerName, Mode=OneWayToSource}" />
Here, typing into the `Entry` will update the `CustomerName` property of the data context.
Two-way binding is the most powerful and commonly used type. It establishes a two-way synchronization between the source and the target. Changes in either the source or the target automatically update the other.
<Entry Text="{Binding UserEmail, Mode=TwoWay}" />
<Slider Value="{Binding VolumeLevel, Mode=TwoWay}" />
When the user types into the `Entry`, `UserEmail` is updated. When `VolumeLevel` changes (e.g., by the `Slider`), the bound property is updated.
In one-time binding, data flows from the source to the target only once, when the binding is initialized. This is useful for properties that are set initially and are not expected to change, or when you want to optimize performance by avoiding further updates.
<TextBlock Text="{Binding AppVersion, Mode=OneTime}" />
The `AppVersion` will be set once and will not be updated even if the `AppVersion` property in the data context changes later.
For data binding to work, the UI element needs to know where to find the data. This is achieved by setting the BindingContext
property.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyApp.ViewModels"
x:Class="MyApp.MyPage">
<ContentPage.BindingContext>
<local:MyViewModel />
</ContentPage.BindingContext>
<!-- UI elements using data binding -->
<Label Text="{Binding WelcomeMessage}" />
</ContentPage>
public partial class MyPage : ContentPage
{
public MyPage()
{
InitializeComponent();
// Assuming MyViewModel is your data context class
BindingContext = new ViewModels.MyViewModel();
}
}
You can bind to any public property of your data context. If you need to bind to a property within a nested object, you can use a dot notation.
<!-- Assuming your data context has a property like 'Customer' which itself has a 'Name' property -->
<Label Text="{Binding Customer.Name}" />
Data binding is particularly powerful when used with collections. .NET MAUI supports binding to collections that implement IList
or IEnumerable
, but for dynamic updates (adding, removing, or reordering items), you should use a collection that implements INotifyCollectionChanged
, such as ObservableCollection<T>
.
<ListView ItemsSource="{Binding Products}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}" Detail="{Binding Price}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
In this example, the `ListView`'s `ItemsSource` is bound to a collection named `Products`. When items are added to or removed from the `ObservableCollection
For data binding to notify the UI when a property's value changes (especially for one-way and two-way binding), your data context class must implement the INotifyPropertyChanged
interface. This interface has a PropertyChanged
event that you raise whenever a property's value is changed.
using System.ComponentModel;
using System.Runtime.CompilerServices;
public class MyViewModel : INotifyPropertyChanged
{
private string _welcomeMessage;
public string WelcomeMessage
{
get { return _welcomeMessage; }
set
{
if (_welcomeMessage != value)
{
_welcomeMessage = value;
OnPropertyChanged(); // Notify that the property has changed
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Tip: The [CallerMemberName]
attribute on the OnPropertyChanged
method is a convenient way to automatically pass the name of the property that is being changed, reducing the chance of typos.