XAML:
<TextBox x:Name="User" Text="{Binding Username}" Margin="0,0,62,0">
<TextBox x:Name="Pass" Text="{Binding Password}" Margin="0,0,62,0">
<Button Command="{Binding Path= SaveCommand}" IsDefault="True" Margin="10,0,1,9" Height="42" VerticalAlignment="Bottom">
如果我删除按钮上的Binding路径,该按钮将再次启用。
视图模型:
public class XViewModel : INotifyPropertyChanged
{
private string _username;
private string _password;
public XViewModel()
{
SaveCommand = new DelegateCommand(Save, () => CanSave);
}
public string Username
{
get { return _username; }
set
{
_username = value;
NotifyOfPropertyChange("Username");
}
}
public string Password
{
get { return _password; }
set
{
_password = value;
NotifyOfPropertyChange("Password");
}
}
protected void NotifyOfPropertyChange(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
public ICommand SaveCommand { get; private set; }
public bool CanSave
{
get { return !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password); }
}
public event PropertyChangedEventHandler PropertyChanged;
public async void Save()
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["StringConnexion"].ConnectionString);
SqlCommand cmd = con.CreateCommand();
cmd.CommandText = "INSERT INTO Users(Login,password)VALUES(@Username,@Password)";
cmd.Parameters.AddWithValue("@ID", Username);
cmd.Parameters.AddWithValue("@FirstName", Password);
try
{
await con.OpenAsync();
cmd.ExecuteNonQuery();
}
catch (SqlException ex)
{
throw ex;
}
finally
{
con.Close();
}
var sampleMessageDialog1 = new SampleMessageDialog
{
Message = { Text = "Connected" }
};
await DialogHost.Show(sampleMessageDialog1, "RootDialog");
}
public class DelegateCommand : ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public DelegateCommand(Action execute)
: this(execute, () => true)
{
_execute = execute;
}
public DelegateCommand(Action execute, Func<bool> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public void Execute(object parameter)
{
_execute();
}
public bool CanExecute(object parameter)
{
return _canExecute();
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
}
我认为它已被禁用,因为一开始没有在TExtbox上写任何内容,但显然情况并非如此。 我基本上使用https://www.codeproject.com/Articles/694908/Connecting-to-SQL-Server-using-MVVM-Pattern进行了一些更改。
修改
如果我使用DataContext执行此操作:
<Button Command="{Binding Path= SaveCommand}" Margin="10,0,1,9" Height="42" Grid.Column="1" Grid.Row="3" VerticalAlignment="Bottom">
<Button.DataContext>
<local:ConnexionViewModel Password="something" Username="sdfsdf" />
</Button.DataContext>
该按钮将启用,something
和sdfsdf
将被添加到数据库中,但又一次,这不是我想要的行为,我希望用户能够通过文本框键入登录名和密码。
答案 0 :(得分:1)
当TextBox的焦点丢失时,TextBox的Text属性会更新。如果在键入内容后从文本框中丢失焦点,则将启用“保存”按钮。如果您希望在键入Text属性后立即更新它,则需要将Binding.UpdateSourceTrigger属性设置为PropertyChanged。
<TextBox x:Name="User" Text="{Binding Username, UpdateSourceTrigger=PropertyChanged}" Margin="0,0,62,0"/>
<TextBox x:Name="Pass" Text="{Binding Password, UpdateSourceTrigger=PropertyChanged}" Margin="0,0,62,0"/>
<Button Command="{Binding Path= SaveCommand}" Content="Save" IsDefault="True" Margin="10,0,1,9" Height="42" VerticalAlignment="Bottom"/>
答案 1 :(得分:0)
在CanExecuteChanged
DelegateCommand
事件
例如
public class DelegateCommand : ICommand {
//...code removed for brevity
public bool CanExecute(object parameter) {
if(_canExecute == null)
return true;
return _canExecute();
}
public void RaiseCanExecuteChanged() {
if( CanExecuteChanged != null ) {
CanExecuteChanged(this, EventArgs.Empty);
}
}
}
以便UI知道视图模型的命令中发生了某些变化,因此它会知道检查/调用CanExecute
并做出相应的反应。
public string Username {
get { return _username; }
set {
_username = value;
NotifyOfPropertyChange("Username");
SaveCommand.RaiseCanExecuteChanged();
}
}
public string Password {
get { return _password; }
set {
_password = value;
NotifyOfPropertyChange("Password");
SaveCommand.RaiseCanExecuteChanged();
}
}
为避免重复代码,您可以使用NotifyOfPropertyChange
方法将代码移至
protected void NotifyOfPropertyChange(string name) {
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) {
handler(this, new PropertyChangedEventArgs(name));
SaveCommand.RaiseCanExecuteChanged();
}
}
这样命令也会在属性更改时引发其事件。由于您的属性很少,因此该建议特定于此方案。