无法获取我按钮的IsEnabled状态进行更改

时间:2019-11-02 23:25:13

标签: android ios xamarin.forms mvvmcross

我已经尝试了很多方法来使它正常工作,但是我显然缺少了某物,因为我的“ Register”按钮不是无论我做什么都可以启用。

在我的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>

在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;
    }

    ...
}

我已经阅读了MvvmCross“文档”,但这全是对话式的,而且我找不到足够具体的绑定到按钮的IsEnabled属性的特定示例,可以带我到那里。

当然会感谢您的帮助。 :)

客房部信息: 我正在使用以下NuGet软件包(/库)
  • MvvmCross和MvvmCross.Forms v6.3.1
  • Xamarin.Forms v4.0.0.497661
  • Xamarin.Android。*库均为v28.0.0.1
然后以为我应该更新,因为有可用的更新,所以我更新到以下内容;
  • MvvmCross和MvvmCross.Forms v6.4.1
  • Xamarin.Forms v4.2.0.848062
  • Xamarin.Android。*库现在均为v28.0.0.3

还对共享内容使用.Net Standard v2.0.3。

2 个答案:

答案 0 :(得分:1)

您可以尝试以下方法:

public class RegisterViewModel : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;
    private bool _isRegisterButtonEnabled;

    public bool IsRegisterButtonEnabled
    {
        set { _isRegisterButtonEnabled = value; PropertyChanged?.Invoke(this, new 
        PropertyChangedEventArgs(nameof(IsRegisterButtonEnabled))); }
        get { return _isRegisterButtonEnabled; }
    }
}

然后用Xaml

<Button Text="Register" 
        Style="{StaticResource RegularButtonStyle}" 
        IsEnabled = "{Binding IsRegisterButtonEnabled}"
        WidthRequest="280"
        x:Name="RegisterButton">
</Button>

答案 1 :(得分:0)

最终答案原来是问题的组合,而其中一个大问题可能需要在SO上发表新的帖子/问题。

所以这就是最终的结果;

我将Xaml更新为以下内容;

<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>

还将RegisterViewModel.cs更新为以下内容;

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;
    }

    ...
}

显然这不是最佳选择。 MvvmCross的{​​{1}}应该触发PropertyChanged事件,由于某种原因,它不会触发。