在不公开模型属性的情况下启用按钮
Enable button without exposing model properties
我在 MVVMHelpers 中使用 MVVM 模式。
我已经制作了登录表单,但我试图仅在用户输入用户名和密码时启用该按钮。
public ICommand LoginCommand { get; set; }
private string _Username;
public string Username {
get { return _Username; }
set {
if (_Username != value) {
_Username = value;
RaisePropertyChanged();
Activate();
}
}
}
private string _Password;
public string Password {
get { return _Password; }
set {
if (_Password != value) {
_Password = value;
RaisePropertyChanged();
Activate();
}
}
}
private bool _IsEnabled;
public bool IsEnabled {
get { return _IsEnabled; }
set {
if (_IsEnabled != value) {
_IsEnabled = value;
RaisePropertyChanged();
}
}
}
public bool Activate() {
if (!string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password)) {
IsEnabled = true;
return true;
}
return false;
}
public LoginVM() {
LoginCommand = new Command(() => {
MessageBox.Show("LogeIn");
});
}
}
如您所见,我通过将 class 的属性公开给我的 VM 来实现这一点。
我想知道是否有办法在不暴露它的情况下做到这一点?
https://github.com/eduardoagr?tab=repositories
您 可以 仅在 XAML 中实现此目的,方法是在 IsEnabled
属性 上使用 [=57] 上的多重绑定=]登录 Button
到用户名和密码 TextBox
es 以及将绑定的 string
s 转换为 bool
的自定义值转换器表示它们是否为空。
但是,在这种情况下这是不可能的,因为您应该避免同时使用 Command
和 IsEnabled
,因为这会导致奇怪的行为。命令提供了一种机制来确定某个操作是否可行,并且 will in turn set the IsEnabled
state.
A command can indicate whether an action is possible by implementing the CanExecute method. A button can subscribe to the CanExecuteChanged event and be disabled if CanExecute returns false or be enabled if CanExecute returns true.
如您所见,同时设置 Command
和 IsEnabled
会相互干扰。虽然它可能有效,但如果您在 XAML 中的 Command
之前指定 IsEnabled
,这是一个脆弱的解决方案,因此请选择一个,在这种情况下支持 Command
及其内置机制.
好消息是,不用在 XAML 中执行此操作,您可以在视图模型中实现相同的操作,并通过将 CanExecute
委托传递给 [=26= 来节省一些代码] 如下。
public class LoginVM : ViewModelBase {
public Command LoginCommand { get; }
private string _Username;
public string Username {
get { return _Username; }
set {
if (_Username != value) {
_Username = value;
RaisePropertyChanged();
LoginCommand.RaiseCanExecuteChanged();
}
}
}
private string _Password;
public string Password {
get { return _Password; }
set {
if (_Password != value) {
_Password = value;
RaisePropertyChanged();
LoginCommand.RaiseCanExecuteChanged();
}
}
}
public LoginVM() {
LoginCommand = new Command(
() => MessageBox.Show("Log IN"),
() => !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password));
}
}
你的命令的第二个参数是一个方法,它确定命令 是否可以执行 如果它 returns true
,绑定的控件返回 false
时,该命令将自动启用或禁用。使用这种方法,您根本不需要 IsEnabled
属性,您可以 将其从 XAML.
中删除
这里唯一需要注意的是,当它需要通过调用其 RaiseCanExecuteChanged
方法(定义在Command
class)。为了访问它,将 属性 的类型从 ICommand
更改为 Command
或为其定义一个单独的支持字段。在这种情况下,每次 Username
或 Password
更改时都需要重新评估,因此将其放入它们的设置器中。
目前,用户名和密码的 TextBox
es 仅在失去焦点时更新视图模型属性(例如,单击它或另一个控件之外)。如果您希望 Sign In 按钮对每次击键做出反应,请将 UpdateSourceTrigger
更改为 PropertyChanged
。
<inputLayout:SfTextInputLayout x:Name="sfTextInputLayout"
Hint="Username"
Margin="20,20,20,0">
<TextBox Foreground="BlanchedAlmond"
Text="{Binding Username, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</inputLayout:SfTextInputLayout>
<controls:CustomPasswordBox Password="{Binding Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
我在 MVVMHelpers 中使用 MVVM 模式。
我已经制作了登录表单,但我试图仅在用户输入用户名和密码时启用该按钮。
public ICommand LoginCommand { get; set; }
private string _Username;
public string Username {
get { return _Username; }
set {
if (_Username != value) {
_Username = value;
RaisePropertyChanged();
Activate();
}
}
}
private string _Password;
public string Password {
get { return _Password; }
set {
if (_Password != value) {
_Password = value;
RaisePropertyChanged();
Activate();
}
}
}
private bool _IsEnabled;
public bool IsEnabled {
get { return _IsEnabled; }
set {
if (_IsEnabled != value) {
_IsEnabled = value;
RaisePropertyChanged();
}
}
}
public bool Activate() {
if (!string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password)) {
IsEnabled = true;
return true;
}
return false;
}
public LoginVM() {
LoginCommand = new Command(() => {
MessageBox.Show("LogeIn");
});
}
}
如您所见,我通过将 class 的属性公开给我的 VM 来实现这一点。 我想知道是否有办法在不暴露它的情况下做到这一点? https://github.com/eduardoagr?tab=repositories
您 可以 仅在 XAML 中实现此目的,方法是在 IsEnabled
属性 上使用 [=57] 上的多重绑定=]登录 Button
到用户名和密码 TextBox
es 以及将绑定的 string
s 转换为 bool
的自定义值转换器表示它们是否为空。
但是,在这种情况下这是不可能的,因为您应该避免同时使用 Command
和 IsEnabled
,因为这会导致奇怪的行为。命令提供了一种机制来确定某个操作是否可行,并且 will in turn set the IsEnabled
state.
A command can indicate whether an action is possible by implementing the CanExecute method. A button can subscribe to the CanExecuteChanged event and be disabled if CanExecute returns false or be enabled if CanExecute returns true.
如您所见,同时设置 Command
和 IsEnabled
会相互干扰。虽然它可能有效,但如果您在 XAML 中的 Command
之前指定 IsEnabled
,这是一个脆弱的解决方案,因此请选择一个,在这种情况下支持 Command
及其内置机制.
好消息是,不用在 XAML 中执行此操作,您可以在视图模型中实现相同的操作,并通过将 CanExecute
委托传递给 [=26= 来节省一些代码] 如下。
public class LoginVM : ViewModelBase {
public Command LoginCommand { get; }
private string _Username;
public string Username {
get { return _Username; }
set {
if (_Username != value) {
_Username = value;
RaisePropertyChanged();
LoginCommand.RaiseCanExecuteChanged();
}
}
}
private string _Password;
public string Password {
get { return _Password; }
set {
if (_Password != value) {
_Password = value;
RaisePropertyChanged();
LoginCommand.RaiseCanExecuteChanged();
}
}
}
public LoginVM() {
LoginCommand = new Command(
() => MessageBox.Show("Log IN"),
() => !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password));
}
}
你的命令的第二个参数是一个方法,它确定命令 是否可以执行 如果它 returns true
,绑定的控件返回 false
时,该命令将自动启用或禁用。使用这种方法,您根本不需要 IsEnabled
属性,您可以 将其从 XAML.
这里唯一需要注意的是,当它需要通过调用其 RaiseCanExecuteChanged
方法(定义在Command
class)。为了访问它,将 属性 的类型从 ICommand
更改为 Command
或为其定义一个单独的支持字段。在这种情况下,每次 Username
或 Password
更改时都需要重新评估,因此将其放入它们的设置器中。
目前,用户名和密码的 TextBox
es 仅在失去焦点时更新视图模型属性(例如,单击它或另一个控件之外)。如果您希望 Sign In 按钮对每次击键做出反应,请将 UpdateSourceTrigger
更改为 PropertyChanged
。
<inputLayout:SfTextInputLayout x:Name="sfTextInputLayout"
Hint="Username"
Margin="20,20,20,0">
<TextBox Foreground="BlanchedAlmond"
Text="{Binding Username, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</inputLayout:SfTextInputLayout>
<controls:CustomPasswordBox Password="{Binding Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />