在WPF MVVM应用程序中没有触发Click事件

时间:2013-11-18 17:54:56

标签: c# .net wpf mvvm

在我的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
    }

0 个答案:

没有答案