【问题标题】:Xamarin button not being enabledXamarin 按钮未启用
【发布时间】:2020-07-25 09:52:55
【问题描述】:

用户注册页面有一个保存工具栏按钮。它总是被禁用。在屏幕上更改参数时不会调用 CanExecute 方法。当用户名和密码不为空且 PW 和 Confirmpassword 字段匹配时,应通过 CanExecute 方法启用 Save 按钮。对三个字段中的任何一个进行更改时,都不会调用 CanExecute 方法。

为什么在三个字段(用户名、密码和 ConfirmPassword)中的任何一个字段中都没有调用 CanExecute 方法三个字段,但显然外部代码未检测到已进行更改。这是某种范围问题吗?

如有必要,整个项目都可用。

吉姆·德宾

Here is the xaml code

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class=*"ButtonTest.RegisterPage"*>
    <ContentPage.ToolbarItems>
        **<ToolbarItem x:Name="registerButton"
            Text="Save"
            Command="{Binding RegisterCommand}"
            CommandParameter="{Binding Password}"/>**
    </ContentPage.ToolbarItems>
    <ContentPage.Content>
        <ScrollView Orientation="Vertical">
            <StackLayout x:Name="containerStackLayout"
                     VerticalOptions="FillAndExpand"                     
                     Margin="20">
                <Label Text="Registration"
                       FontSize="Large"
                       HorizontalOptions="Center"
                       FontAttributes="Bold"></Label>
                <Entry x:Name="UserName"
                    Placeholder="User Name"
                    Text="{Binding UserName, Mode=TwoWay}"
                    Keyboard="Text"/>
                <Entry x:Name="PasswordEntry"
                    Placeholder="Password"
                    Text="{Binding PW, Mode=TwoWay}"
                    IsPassword="True"/>
                <Entry x:Name="confirmPasswwordEntry"
                    Placeholder="Confirm Password"
                    Text="{Binding ConfirmPassword, Mode=TwoWay}"
                    IsPassword="True"/>
                <Entry x:Name="Email"
                    Placeholder="Email"
                    Text="{Binding Email, Mode=TwoWay}"
                    Keyboard="Email"/>
            </StackLayout>
        </ScrollView>
    </ContentPage.Content>
</ContentPage>

viewModel code 

using ButtonTest.Model;
using System.ComponentModel;
using ButtonTest.ViewModel.Commands;

namespace ButtonTest.ViewModel
{
    public class RegisterPageVM : INotifyPropertyChanged
    {
        public RegisterCommand RegisterCommand { get; set; }

        private Password user;
        public Password User
        {
            get { return user; }
            set
            {
                user = value;
                OnPropertyChanged("User");
            }
        }


        private string username;
        public string UserName
        {
            get { return username; }
            set
            {
                username = value;
                User = new Password()
                {
                    UserName = this.UserName,
                    PW = this.PW,
                    ConfirmPassword = this.ConfirmPassword
                };
                OnPropertyChanged("UserName");
            }
        }

        private string pw;
        public string PW
        {
            get { return pw; }
            set
            {
                pw = value;
                User = new Password()
                {
                    UserName = this.UserName,
                    PW = this.PW,
                    ConfirmPassword = this.ConfirmPassword
                };
                OnPropertyChanged("PW");
            }
        }

        private string confirmpassword;
        public string ConfirmPassword
        {
            get { return confirmpassword; }
            set
            {
                confirmpassword = value;
                User = new Password()
                {
                    UserName = this.UserName,
                    PW = this.PW,
                    ConfirmPassword = this.ConfirmPassword
                };
                OnPropertyChanged("ConfirmPassword");
            }
        }
        public RegisterPageVM()
        {
            RegisterCommand = new RegisterCommand(this);
            //User = new Password();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        public void Register(Password user)
        {
            Password.Register(user);
        }
    }
}

Here is the command code

using System;
using System.Windows.Input;
using ButtonTest.Model;

namespace ButtonTest.ViewModel.Commands
{
    public class RegisterCommand : ICommand
    {
        private RegisterPageVM viewModel;

        public RegisterCommand(RegisterPageVM viewModel)
        {
            this.viewModel = viewModel;
        }

        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            Password user = (Password)parameter;
            if (user != null)
            {
                if (user.PW == user.ConfirmPassword)
                {
                    if (string.IsNullOrEmpty(user.UserName) || string.IsNullOrEmpty(user.PW))
                        return false;
                    return true;
                }
                return false;
            }
            return false;
        }

        public void Execute(object parameter)
        {
            Password user = (Password)parameter;
            viewModel.Register(user);
        }
    }
}

这里是 Password.cs 代码

    using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Numerics;
using System.Linq;
using System.Threading.Tasks;

namespace ButtonTest.Model
{
    public class Password : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        private string username;
        public string UserName
        {
            get { return username; }
            set
            {
                username = value;
                OnPropertyChanged("UserName");
            }
        }

        private string pw;
        public string PW
        {
            get { return pw; }
            set
            {
                pw = value;
                OnPropertyChanged("PW");
            }
        }

        private string confirmPassword;
        public string ConfirmPassword
        {
            get { return confirmPassword; }
            set
            {
                confirmPassword = value;
                OnPropertyChanged("ConfirmPassword");
            }
        }

        private string email;
        public string Email
        {
            get { return email; }
            set { email = value; }
        }

        public static async void Insert(Password password)
        {
            await App.client.GetTable<Password>().InsertAsync(password);
            //await App.client.SyncContext.PushAsync();

        }
        public static async Task<bool> Delete(Password password)
        {
            try
            {
                await App.passwordsTable.DeleteAsync(password);
                //await App.client.SyncContext.PushAsync();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public static async void Register(Password user)
        {
            await App.client.GetTable<Password>().InsertAsync(user);
        }
        public static async Task<bool> Login(string username, string password)
        {
            bool isEmailEmpty = string.IsNullOrEmpty(username);
            bool isPasswordEmpty = string.IsNullOrEmpty(password);
            if (isEmailEmpty || isPasswordEmpty)
            {
                return false;
            }
            else
            {
                var user = (await App.client.GetTable<Password>().Where(u => u.UserName == username).ToListAsync()).FirstOrDefault();
                if (user != null)
                {
                    App.user = user;
                    if (user.pw == password)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
        }
    }
}

【问题讨论】:

  • 这个模型的数据是什么?你怎么绑定这个? Password 的更多详细信息也会有所帮助。
  • 我不知道你对这个模型的数据的第一个问题想要什么。仅在屏幕上的用户名字段中输入字母“a”,在 PW 和 ConfirmPassword 字段中输入字母“b”不会启用按钮。
  • Password.cs 代码已添加到原帖中
  • 将整个 buttontest 项目转发给您会有帮助吗?我不知道该怎么做。
  • 重新绑定 - 在 xaml 代码中。按钮的绑定是到 VM 中的 RegisterCommand。数据字段绑定到 VM 中的属性。

标签: xamarin button


【解决方案1】:

这个问题解决了。 RegisterCommand 的 CommandParameter 绑定需要设置为 VM 中的 User 属性。现在,对于 UserName、PW 和 ConfirmPassword 字段中的每次更改都会调用 CanExecute 方法。

E.Z. 解决了这个问题。来自 github 支持小组的 Hart。非常感谢您的解决方案。

【讨论】:

  • 感谢分享。不要忘记接受答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 2020-06-20
  • 2013-08-01
  • 2013-02-12
  • 1970-01-01
相关资源
最近更新 更多