I have a small example below in .net maui 9, where I am setting a property in my view model via a CommandParameter
value that is being set when a button is clicked in the view.
This property is then used as a BindingContext
for the PlaceHolderText
property for an Entry
view. So the text that should be displayed in Entry
when Set PropertyOne
Button is clicked is Text from Property
.
Code below for View:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiBindingExample.MainPage"
xmlns:local="clr-namespace:MauiBindingExample.ViewModels">
<ScrollView>
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<Image
Source="dotnet_bot.png"
HeightRequest="185"
Aspect="AspectFit"
SemanticProperties.Description="dot net bot in a hovercraft number nine" />
<Button
BindingContext="{local:ExampleViewModel}"
x:DataType="local:ExampleViewModel"
Text="Set PropertyOne"
Command="{Binding SetPropertyOneCommand}"
CommandParameter="Text from Property"/>
<Entry
BindingContext="{local:ExampleViewModel}"
x:DataType="local:ExampleViewModel"
PlaceholderColor="AliceBlue"
Placeholder="{Binding EntryPlaceholderText}"/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
Code below for View Model:
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
namespace MauiBindingExample.ViewModels
{
public class ExampleViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string entryPlaceholderText;
public string EntryPlaceholderText
{
get => entryPlaceholderText;
set
{
entryPlaceholderText = value;
OnPropertyChanged();
}
}
public ICommand SetPropertyOneCommand { get; set; }
public ExampleViewModel()
{
SetPropertyOneCommand = new Command<string>(
(string arg) =>
{
EntryPlaceholderText = arg;
});
}
public void OnPropertyChanged([CallerMemberName] string propertyName="")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
When I set a debugger, I can confirm that the property EntryPlaceholderText
is set correctly when Set PropertyOne
button is clicked, but then after the Command execution is complete the property EntryPlaceholderText
is reset so there is no Entry
placeholder text displayed.
What could be the issue?
Help is much appreciated.
You're currently setting two different instances of ExampleViewModel
as BindingContext
for the two components (Button
and Entry
).
You should set BindingContext
only at the page level and let it be inherited by all the controls you put in that page. So:
BindingContext
from these controls<Button
Text="Set PropertyOne"
Command="{Binding SetPropertyOneCommand}"
CommandParameter="Text from Property"/>
<Entry
PlaceholderColor="AliceBlue"
Placeholder="{Binding EntryPlaceholderText}"/>
BindingContext
at page level (I'm assuming you're not using dependency injection for viewmodels).<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiBindingExample.MainPage"
BindingContext="{local:ExampleViewModel}"
x:DataType="local:ExampleViewModel"
xmlns:local="clr-namespace:MauiBindingExample.ViewModels">
...
</ContentPage>
Just a note outside the scope of the question. Consider using the MVVM Community Toolkit. You'll get rid of a lot of boilerplate code.