I have a ContentPage that is binded to a ViewModel and I want to update the visibility of a button from the ViewModel. If I remove the Path, the binding works, but it doesn't update in the view when I change it in the viewModel. With the Path set, nothing seems to work. Does anyone have any experience doing this in code as opposed to xaml? Here is what I have so far.
From viewModel:
public bool DoneIsAvailable { get { return _doneIsAvailable; } set { _doneIsAvailable = value; OnPropertyChanged("ShowDone"); } }
And here from the ContentPage
var doneButton = new Button { BackgroundColor = Color.Gray, Text = "Done", TextColor = Color.Blue, FontSize = 15, Command = viewModel.DoneButton }; Binding doneBinding = new Binding { Source = viewModel.DoneIsAvailable, Path = "ShowDone", Mode = BindingMode.OneWay, }; doneButton.SetBinding(IsVisibleProperty, doneBinding);
The name of the property you're binding to and the name you pass into OnPropertyChanged
must be the same. The nameof
operator is extremely useful for this, or if your implementation of OnPropertyChanged
uses the [CallerMemberName]
attribute for its parameter you don't even need to pass anything in when you call it from a setter. (BindableObject
has this attribute.)
ViewModel:
public bool DoneIsAvailable { get { return _doneIsAvailable; } set { _doneIsAvailable = value; OnPropertyChanged(nameof(DoneIsAvailable); } }
Page:
doneButton.SetBinding(IsVisibleProperty, nameof(viewModel.DoneIsAvailable));
Answers
I still would like to know the correct way to get this binding to update but, I was able to work-around this issue by creating a button in my viewModel and referencing it in my view. Then when I dynamically updated the button in my viewModel, it also updated in my view.
@StephenHarris
Try changing the binding mode to BindingMode.TwoWay.
The name of the property you're binding to and the name you pass into
OnPropertyChanged
must be the same. Thenameof
operator is extremely useful for this, or if your implementation ofOnPropertyChanged
uses the[CallerMemberName]
attribute for its parameter you don't even need to pass anything in when you call it from a setter. (BindableObject
has this attribute.)ViewModel:
Page:
You nailed it JoeManke! I made sure the property name was the same name I passed to
OnPropertyChanged
and used thenameof
operator. It works like it's supposed to. Thank you very much!