xamarin - Xamarin 按钮未启用
问题描述
用户注册页面有一个保存工具栏按钮。它总是被禁用。在屏幕上更改参数时不会调用 CanExecute 方法。当用户名和密码不为空且 PW 和 Confirmpassword 字段匹配时,应通过 CanExecute 方法启用 Save 按钮。当对三个字段中的任何一个进行更改时,不会调用 CanExecute 方法。
当在三个字段(用户名、密码和 ConfirmPassword )中的任何一个字段中输入内容时,为什么不为 registerButton 调用 CanExecute 方法 OnPropertyChanged 方法被调用以对这三个字段进行任何更改,但显然外部代码不是检测到发生了变化。这是某种范围问题吗?
如有必要,整个项目都可用。
吉姆·德宾
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;
}
}
}
}
}
解决方案
这个问题就解决了。RegisterCommand 的 CommandParameter 绑定需要设置为 VM 中的 User 属性。现在,对于 UserName、PW 和 ConfirmPassword 字段中的每次更改都会调用 CanExecute 方法。
它由 github 支持组的 EZ Hart 解决。非常感谢您的解决方案。
推荐阅读
- r - Dplyr,如果向量列表中存在任何值,则过滤组
- javascript - 使用 preventDefault 覆盖打开新标签
- python - 如何在没有 Pandas 的情况下迭代列表列表中的列并更改值
- vagrant - vagrant 2.2.7 - 不能 vagrant up:默认值:警告:身份验证失败。重试
- spring-boot - JSON 解析错误:无法构造 `org.test.dtos.TestChild` 的实例(尽管至少存在一个 Creator)
- c# - 了解 C# 中的资源/资源文件及其用途的问题
- mariadb - mariadb.service:无法设置挂载命名空间:权限被拒绝/在命名空间生成步骤中失败
- python - pandas multiindex - 根据子索引的数量删除行
- dictionary - 如何将 JuMP 变量的值存储到 julia 中的嵌套字典中
- google-apps-script - 我可以使用 DriveApp searchFiles 功能来查找祖父母而不是父文件夹吗?