Reputation: 6202
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
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
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
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