To illustrate the problem I created a custom control PingPongView
with the following behavior:
- if the
Ping
button is pressed then a star*
is appended to itsMessage
. - if the
Pong
button is press then the last character inMessage
is removed.
public partial class PingPongViewModel : ObservableObject
{
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(PongCommand))]
string _message = string.Empty;
bool IsMessageNotEmpty => Message != string.Empty;
[RelayCommand]
void Ping() => Message += "*";
[RelayCommand(CanExecute = nameof(IsMessageNotEmpty))]
void Pong() => Message = Message.Substring(0, Message.Length - 1);
}
public partial class PingPongView : ContentView
{
public static readonly BindableProperty MessageProperty =
BindableProperty.Create(
propertyName: nameof(Message),
returnType: typeof(string),
declaringType: typeof(PingPongView),
defaultBindingMode: BindingMode.TwoWay,
propertyChanged: OnMessagePropertyChanged);
public string Message
{
get => (string)GetValue(MessageProperty);
set => SetValue(MessageProperty, value);
}
static void OnMessagePropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var view = (PingPongView)bindable;
view._model.Message = (string)newValue;
}
PingPongViewModel _model;
public PingPongView()
{
InitializeComponent();
_model = new PingPongViewModel();
BindingContext = _model;
}
}
<ContentView ... others are trimmed ...
x:DataType="loc:PingPongViewModel">
<HorizontalStackLayout >
<Button Text="Ping" Command="{Binding PingCommand}" />
<Button Text="Pong" Command="{Binding PongCommand}" />
</HorizontalStackLayout>
</ContentView>
I used PingPongView
in MainPage
as follows:
<Entry x:Name="Entry" Text="0" />
<loc:PingPongView Message="{Binding Text,Source={Reference Entry}}" />
<Entry Text="{Binding Message,Source={Reference PingPongView}}" />
<loc:PingPongView x:Name="PingPongView" />
Unfortunately in both cases, the Text
of Entry
controls don’t reflect changes in PingPongView
. What am I wrong here?
3