【问题标题】:CAN NOT get my button's IsEnabled state to change无法更改按钮的 IsEnabled 状态
【发布时间】:2020-02-28 18:00:09
【问题描述】:

我已经尝试了无数种方法到星期天来让它工作,但我显然缺少一些东西,因为我的“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 包 (/libraries)
  • 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 来共享内容。

【问题讨论】:

  • 首先,是否需要触发器?您不能直接将 IsEnabled 绑定到您的 VM 属性吗?其次,我没有看到任何实际设置 IsRegisterButtonEnabled
  • @Jason 我试过了。这就是那些以&lt;!-- I HAD the following,... 开头的 [在 XAML 中] 的 cmets 的意思。
  • 好的,但是我没有看到任何设置 IsRegisterButtonEnabled 的地方?
  • @Jason Oi,你是绝对正确的!虽然我的问题结果是多种因素的结合,但这绝对是其中之一。

标签: android ios xamarin.forms mvvmcross


【解决方案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>

【讨论】:

  • 嗯,嗯,我很确定这就是为什么我的 ViewModel 继承自 MvxViewModel 并且我正在调用 SetProperty() 来设置值。如果我删除这些东西,我为什么要使用MvvmCross?也就是说,我会给出这个并尝试看看会发生什么。
【解决方案2】:

最终的答案原来是多个问题的组合,其中一个大问题可能需要在 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;
    }

    ...
}

显然这不是最优的。 MvvmCrossSetProperty() 应该触发 PropertyChanged 事件,但由于某种原因它没有。

【讨论】:

  • 能否将您的回复标记为答案,以便其他人在遇到类似问题时得到帮助?
  • 当然!抱歉,我想当我点击自动发生的Answer your question 按钮时我想。
猜你喜欢
  • 2011-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-11
  • 2021-07-11
  • 2019-12-21
  • 1970-01-01
相关资源
最近更新 更多