I have tried umpteen-ways-to-Sunday to get this to work, but I'm obviously missing something because my "Register
" button is not getting enabled no matter what I do.
In my XAML:
<Button Text="Register"
Style="{StaticResource RegularButtonStyle}"
WidthRequest="280"
x:Name="RegisterButton">
<!-- I HAD the following, but it wasn't working so I finally decided to try DataTriggers -->
<!-- bindings:Bi.nd="Clicked RegisterButtonClickedCommand;IsEnabled IsRegisterButtonEnabled"> -->
<Button.Triggers>
<DataTrigger TargetType="Button"
Binding="{Binding IsRegisterButtonEnabled}"
Value="False">
<Setter Property="IsEnabled" Value="False"></Setter>
</DataTrigger>
<DataTrigger TargetType="Button"
Binding="{Binding IsRegisterButtonEnabled}"
Value="True">
<Setter Property="IsEnabled" Value="True"></Setter>
</DataTrigger>
</Button.Triggers>
</Button>
In the ViewModel:
public class RegisterViewModel : MvxViewModel
{
...
private bool _isRegisterButtonEnabled;
public bool IsRegisterButtonEnabled
{
get => ShouldEnableRegisterButton();
set
{
_isRegisterButtonEnabled = value;
SetProperty(ref _isRegisterButtonEnabled, value);
}
}
...
public IMvxCommand RegisterButtonClickedCommand { get; private set; }
...
private void InitializeCommands()
{
...
RegisterButtonClickedCommand = new MvxCommand(RegisterUser);
}
...
private bool ShouldEnableRegisterButton()
{
var isValidUser = _userName.Validate();
var isValidPass = _password.Validate();
var isValidConfirmedPass = _confirmedPassword.Validate();
var shouldEnable = isValidUser && isValidPass && isValidConfirmedPass;
_mvxLogger.Log(MvxLogLevel.Trace, () => $"RegisterViewModel : ShouldEnableRegisterButton() called. Returning: {shouldEnable}");
return shouldEnable;
}
...
}
I've read the MvvmCross "Documentation" but it's all conversational and I can't find any SPECIFIC examples of binding to a button's IsEnabled property with enough specificity to get me there.
Sure would appreciate some help. :)
Housekeeping information: I was using the following NuGet packages (/libraries)Also using .Net Standard v2.0.3 for the Shared stuff.
The Final Answer turned out to be a combination of issues, and one big one that will probably require a new post/question here on SO.
So here's what ended up working;
I updated the Xaml to the following;
<Button Text="Register"
Style="{StaticResource RegularButtonStyle}"
WidthRequest="280"
x:Name="RegisterButton"
Command="{Binding RegisterButtonClickedCommand}">
<Button.Triggers>
<DataTrigger TargetType="Button"
Binding="{Binding IsRegisterButtonEnabled}"
Value="False">
<Setter Property="IsEnabled" Value="False"></Setter>
</DataTrigger>
<DataTrigger TargetType="Button"
Binding="{Binding IsRegisterButtonEnabled}"
Value="True">
<Setter Property="IsEnabled" Value="True"></Setter>
</DataTrigger>
</Button.Triggers>
</Button>
Also updated RegisterViewModel.cs to the following;
public class RegisterViewModel : MvxViewModel, INotifyPropertyChanged
{
...
// Added this (and the inheriting from INotify.. [per @Adlorem]
public event PropertyChangedEventHandler PropertyChanged;
private bool _isRegisterButtonEnabled;
public bool IsRegisterButtonEnabled
{
get
{
_mvxLogger.Log(MvxLogLevel.Trace,
() => $"RegisterViewModel : IsRegisterButtonEnabled property get called. Returning: {_isRegisterButtonEnabled}");
return _isRegisterButtonEnabled;
}
set
{
_isRegisterButtonEnabled = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsRegisterButtonEnabled)));
_mvxLogger.Log(MvxLogLevel.Trace,
() => $"RegisterViewModel : IsRegisterButtonEnabled property set called. value: {value}");
}
}
...
private bool ShouldEnableRegisterButton()
{
var isValidUser = _userName.Validate();
var isValidPass = _password.Validate();
var isValidConfirmedPass = _confirmedPassword.Validate();
var shouldEnable = isValidUser && isValidPass && isValidConfirmedPass;
// Must set this or the PropertyChanged definitely won't fire!
IsRegisterButtonEnabled = shouldEnable;
_mvxLogger.Log(MvxLogLevel.Trace,
() => $"RegisterViewModel : ShouldEnableRegisterButton() called. Returning: {shouldEnable}");
return shouldEnable;
}
...
}
Obviously this is not optimal. MvvmCross
's SetProperty()
should be firing the PropertyChanged event and for some reason it doesn't.