在我的WPF MVVM项目应用程序中,单击事件命令(AddUserCmd)未被触发。你可以从我的代码部分找出问题吗?
User.xaml
<Window x:Class="JP.User"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="Window" Title="User" WindowStartupLocation="CenterScreen"
Width="795" Height="500">
...
...
<TextBox Canvas.Left="114" TextWrapping="Wrap" Canvas.Top="98" RenderTransformOrigin="-0.093,-0.274" Width="157" Height="20" Background="{x:Null}" Foreground="#FF6B6C6C" Text="{Binding Path=Name}">
<TextBox Canvas.Left="114" TextWrapping="Wrap" Canvas.Top="129" RenderTransformOrigin="-0.093,-0.274" Width="157" Height="21" Background="{x:Null}" Foreground="#FF6B6C6C" Text="{Binding Path=Pwd}">
...
...
<Button Content="Save" Height="23" Name="button2" Width="75" Margin="605,0,0,0" Command="{Binding AddUserCmd}"/>
...
...
</Window>
UserViewModel.cs
public class UserViewModel : INotifyPropertyChanged
{
#region Private Variables
//The Variables are meant to be readonly as we mustnot change the address of any of them by creating new instances.
//Problem with new istances is that since address changes the binding becomes invalid.
//Instantiate all the variables in the constructor.
private readonly JanathaPOS.Model.User _user;
private readonly ObservableCollection<JanathaPOS.Model.User> _users;
private readonly UserManager _userManager;
private readonly ICommand _addUserCmd;
//private readonly ICommand _deleteUserCmd;
#endregion
#region Constructors
/// <summary>
/// Instatiates all the readonly variables
/// </summary>
public UserViewModel()
{
_user = new JanathaPOS.Model.User();
_userManager = new UserManager();
_users = new ObservableCollection<Model.User>();
_addUserCmd = new RelayCommand(Add, CanAdd);
}
#endregion
#region Public Properties
/// <summary>
/// Gets or Sets User Name. Ready to be binded to UI.
/// Impelments INotifyPropertyChanged which enables the binded element to refresh itself whenever the value changes.
/// </summary>
public string Name
{
get
{
return _user.Name;
}
set
{
_user.Name = value;
OnPropertyChanged("Name");
}
}
/// <summary>
/// Gets or Sets User Password. Ready to be binded to UI.
/// Impelments INotifyPropertyChanged which enables the binded element to refresh itself whenever the value changes.
/// </summary>
public string Pwd
{
get
{
return _user.Pwd;
}
set
{
_user.Pwd = value;
OnPropertyChanged("Pwd");
}
}
/// <summary>
/// Gets the Users. Used to maintain the User List.
/// Since this observable collection it makes sure all changes will automatically reflect in UI
/// as it implements both CollectionChanged, PropertyChanged;
/// </summary>
public ObservableCollection<JanathaPOS.Model.User> Users
{
get
{
return _users;
}
}
#endregion
#region Command Properties
/// <summary>
/// Gets the AddPatientCommand. Used for Add patient Button Operations
/// </summary>
public ICommand AddUserCmd
{
get
{
return _addUserCmd;
}
}
#endregion
#region Commands
#region AddCommand
/// <summary>
/// Add operation of the AddUserCmd.
/// Operation that will be performormed on the control click.
/// </summary>
/// <param name="obj"></param>
public void Add(object obj)
{
//Always create a new instance of patient before adding.
//Otherwise we will endup sending the same instance that is binded, to the BL which will cause complications
var user = new JanathaPOS.Model.User { Id = "123", Name = Name, Pwd = Pwd };
//Add patient will be successfull only if the patient with same ID does not exist.
if (_userManager.Add(user))
{
Users.Add(user);
ResetUser();
MessageBox.Show("User add Successful!");
}
else
{
MessageBox.Show("User with this ID already exists!");
}
}
/// <summary>
/// CanAdd operation of the AddUserCmd.
/// Tells us if the control is to be enabled or disabled.
/// This method will be fired repeatedly as long as the view is open.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public bool CanAdd(object obj)
{
//Enable the Button only if the mandatory fields are filled
if (Name != string.Empty && Pwd != string.Empty)
return true;
return false;
}
#endregion
#endregion
#region Private Methods
/// <summary>
/// Resets the Patient properties which will in turn auto reset the UI aswell
/// </summary>
private void ResetUser()
{
//Id = string.Empty;
Name = string.Empty;
Pwd = string.Empty;
}
#endregion
#region INotifyPropertyChanged Members
/// <summary>
/// Event to which the view's controls will subscribe.
/// This will enable them to refresh themselves when the binded property changes provided you fire this event.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// When property is changed call this method to fire the PropertyChanged Event
/// </summary>
/// <param name="propertyName"></param>
public void OnPropertyChanged(string propertyName)
{
//Fire the PropertyChanged event in case somebody subscribed to it
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
RelayCommand.cs
public class RelayCommand: ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
/// <summary>
/// Creates a new command that can always execute.
/// </summary>
/// <param name="execute">The execution logic.</param>
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
/// <summary>
/// Creates a new command.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion // ICommand Members
}