Reputation: 1128
When binding a value to a Label.Text it works fine but doing the same with Entry.Text I see the initial value but this never updates when the value changes. Here is xaml for Label:
<Label x:Name="multiplierLabel" VerticalOptions="Center"
FontSize="22"
HorizontalTextAlignment="Center"
Text="{Binding Source={x:Reference ControlView}, Path=Multiplier}"
Padding="16,0, 0,0"/>
and Entry:
<Entry
HorizontalTextAlignment="Center"
TextChanged="Entry_TextChanged"
Focused="Entry_Focused"
Keyboard="Numeric"
FontSize="22"
Text="{Binding Source={x:Reference ControlView}, Path=MultiplierB}"
>
</Entry>
Both items are bound to the same value in the View Model:
Multiplier="{Binding CurrentActionRow.Multiplier}"
MultiplierB="{Binding CurrentActionRow.Multiplier}"
and the code behind is identical for both:
public string Multiplier
{
get => (string)GetValue(MultiplierProperty);
set => SetValue(MultiplierProperty, value);
}
public static readonly BindableProperty MultiplierProperty =
BindableProperty.Create(
nameof(Multiplier),
typeof(string),
typeof(ActionRowElement),
"Multiplier Not Set");
public string MultiplierB
{
get => (string)GetValue(MultiplierBProperty);
set => SetValue(MultiplierBProperty, value);
}
public static readonly BindableProperty MultiplierBProperty =
BindableProperty.Create(
nameof(MultiplierB),
typeof(string),
typeof(ActionRowElement),
"MultiplierB Not Set");
Can anybody help get the Text value to update in the Entry element when the bound value changes?
Upvotes: 0
Views: 2658
Reputation: 13853
You can try to change the BindingMode
of your property to TwoWay
.
I created a demo and did a test, and it works properly on my side.
You can refer to the following code:
ChildView.xaml.cs
public partial class ChildView : ContentView
{
//other code
public string Multiplier
{
get => (string)GetValue(MultiplierProperty);
set => SetValue(MultiplierProperty, value);
}
public static readonly BindableProperty MultiplierProperty =
BindableProperty.Create(
nameof(Multiplier),
typeof(string),
typeof(ChildView),
defaultBindingMode: BindingMode.TwoWay);
public string MultiplierB
{
get => (string)GetValue(MultiplierBProperty);
set => SetValue(MultiplierBProperty, value);
}
public static readonly BindableProperty MultiplierBProperty =
BindableProperty.Create(
nameof(MultiplierB),
typeof(string),
typeof(ChildView),
defaultBindingMode: BindingMode.TwoWay);
public ChildView()
{
InitializeComponent();
}
}
ChildView.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"
x:Class="MauiContentViewApp.ChildView"
x:Name="TestControlView"
>
<VerticalStackLayout>
<Label Text="{Binding Source={x:Reference TestControlView}, Path=Multiplier}"
VerticalOptions="Center"
HorizontalOptions="Center" />
<Entry Text="{Binding Source={x:Reference TestControlView}, Path=MultiplierB}"
VerticalOptions="Center"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentView>
MainPage.xaml
<?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"
xmlns:mauiapp="clr-namespace:MauiContentViewApp"
x:Class="MauiContentViewApp.MainPage"
x:Name="mainpage"
>
<ScrollView>
<VerticalStackLayout>
<mauiapp:ChildView
Multiplier="{Binding TestName}"
MultiplierB="{Binding TestName}"
>
</mauiapp:ChildView>
<Button Text="Change" Command="{Binding ChangeNameCommand}"></Button>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
MainPage.xaml.cs
public MainPage()
{
InitializeComponent();
this.BindingContext = new MyViewModel();
}
MyViewModel.cs
public class MyViewModel: INotifyPropertyChanged
{
private string _testName;
public string TestName
{
set { SetProperty(ref _testName, value); }
get { return _testName; }
}
public ICommand ChangeNameCommand => new Command(changeMethod);
private void changeMethod()
{
index++;
TestName = "change data" + index;
}
public MyViewModel()
{
TestName = "test string";
}
bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
Upvotes: 1