Enrico
Enrico

Reputation: 6202

MAUI ContentView doesn't bind the properties

I like to create a custom component with MAUI. For this reason, I create a ContentView and I added some BindableProperty like this one:

public static readonly BindableProperty UserAnswerProperty = 
        BindableProperty.Create(nameof(UserAnswer), typeof(string), 
        typeof(DictionaryHeader));

public string UserAnswer
{
    get => GetValue(UserAnswerProperty) as string;
    set => SetValue(UserAnswerProperty, value);
}

Now, I added the XAML to display an Edit and I want to bind the BindableProperty UserAnswer to this component. So, I wrote this XAML.

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:bh="clr-namespace:LanguageInUse.Behaviors"
             xmlns:lang="clr-namespace:LanguageInUse"
             x:Class="LanguageInUse.Components.WordCheck"
             x:Name="wc">

    <VerticalStackLayout>
        <Entry x:Name="editAnswer" Text="{Binding UserAnswer}">
        <Button x:Name="buttonConfirm" Text="Confirmed"
               Clicked="buttonConfirm_Clicked">
    </VerticalStackLayout>
</ContentView>

When I click the button and inspect the property UserAnswer, this is empty. So, the binding is not passing the value.

How can I do that? Do I have to create a ViewModel with an ObservableObject?

Upvotes: 1

Views: 1584

Answers (3)

Enrico
Enrico

Reputation: 6202

The solution I found is quite straightforward. It is enough to add the BindingContext to the same page in a control like the VerticalStackLayout.

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:bh="clr-namespace:LanguageInUse.Behaviors"
             xmlns:lang="clr-namespace:LanguageInUse"
             x:Class="LanguageInUse.Components.WordCheck"
             x:Name="wc">

    <VerticalStackLayout BindingContext="{x:Reference wc}">
        <Entry x:Name="editAnswer" Text="{Binding UserAnswer}">
        <Button x:Name="buttonConfirm" Text="Confirmed"
               Clicked="buttonConfirm_Clicked">
    </VerticalStackLayout>
</ContentView>

Upvotes: 2

Guangyu Bai - MSFT
Guangyu Bai - MSFT

Reputation: 4486

The purpose of bindable properties is to provide a property system that supports data binding, styles, templates, and values set through parent-child relationships. It is used to create properties for the elements. You can read the document about Bindable properties.

If you want to use the UserAnswerProperty you created, you can create the entry like this:

<VerticalStackLayout>
        <Entry x:Name="editAnswer" UserAnswer = "text">
        <Button x:Name="buttonConfirm" Text="Confirmed"
               Clicked="buttonConfirm_Clicked">
 </VerticalStackLayout>

Besides, If you do not know how to bind the data to the text of the entry, you can create a viewmodel and realize the UserAnswer then bind the viewmodel to the Xaml

public partial class MyViewModel : ObservableObject, INotifyPropertyChanged
   {
       [ObservableProperty]
       string _userAnswer;
        public MyViewModel()
       {
           UserAnswer = "answer";
       }
      
    }

The code in the Mainpage code behind:

public MainPage()
    {
        InitializeComponent();
        
        BindingContext = new MyViewModel();
    }

The code in the Mainpage.xaml:

 <VerticalStackLayout>
        <Entry x:Name="editAnswer" Text="{Binding UserAnswer}">
        <Button x:Name="buttonConfirm" Text="Confirmed"
               Clicked="buttonConfirm_Clicked">
    </VerticalStackLayout>

Upvotes: 0

Peter Wessberg
Peter Wessberg

Reputation: 1911

What is happening is that with the Binding, you are looking for data where the BindingContext is pointing to. Normally it is to your ViewModel. If you want to bind to the ContentView and its BindableProperty you reference them by the name of the xaml, in your case wc. There are other ways to do this.

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:bh="clr-namespace:LanguageInUse.Behaviors"
             xmlns:lang="clr-namespace:LanguageInUse"
             x:Class="LanguageInUse.Components.WordCheck"
             x:Name="wc">

    <VerticalStackLayout>
        <Entry x:Name="editAnswer" Text="{Binding UserAnswer, Source={x:Reference wc}}">
        <Button x:Name="buttonConfirm" Text="Confirmed"
               Clicked="buttonConfirm_Clicked">
    </VerticalStackLayout>
</ContentView>

Upvotes: 4

Related Questions