Question

Disclaimer: I'm still learning MVVM and WPF so this might just be a ICommand vs RelayCommand question for all I know. I'm not using a MVVM framework or the like, just VS2010.

Currently I have a MainWindow with a Login button that opens a child window. I've been able to make this happen by using either:

  • standard ICommand that has all the code for opening the menu in the Command file and View XAML with a StaticResource Binding and Key (no code in the ViewModel)
  • RelayCommand command file that defines a standard RelayCommand, ViewModel that defines a RelayCommand "ButtonCommand" that opens the child, and View XAML that defines a ViewModel DataContext and a ButtonCommand Command Binding

Is there a "proper" or "community standard" way that the code should be organized? In either approach, is the way I'm setting it up improper?

Way 1: OpenLoginPrompt ICommand File:

namespace SafetyTraining.Commands
{
    public class OpenLoginPrompt : ICommand
    {
        public bool CanExecute(object parameter)
        {
            return true;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            LoginPrompt login = new LoginPrompt();
            login.ShowDialog();
        }
    }
}

Way 2: RelayCommand File

namespace SafetyTraining.Commands
{
    class RelayCommand : ICommand
    {
        private Action<object> _action;
        public RelayCommand(Action<object> action)
        {
            _action = action;
        }
        #region ICommand Members
        public bool CanExecute(object parameter)
        {
            return true;
        }
        public event EventHandler CanExecuteChanged;
        public void Execute(object parameter)
        {
            if (parameter != null)
            {
                _action(parameter);
            }
        }
        #endregion
    }
}

MainWindowViewModel

namespace SafetyTraining.ViewModels
{
    class MainWindowVM
    {
        private ICommand m_ButtonCommand;
        public ICommand ButtonCommand
        {
            get
            {
                return m_ButtonCommand;
            }
            set
            {
                m_ButtonCommand = value;
            }
        }

        public MainWindowVM()
        {
            ButtonCommand = new RelayCommand(new Action<object>(LoginOpen));
        }

        public void LoginOpen(object obj)
        {
            LoginPrompt login = new LoginPrompt();
            login.ShowDialog();
        }
    }
}

Addtional Question: Should Commands be in separate CS files (what I'm currently doing) or be part of the Model/ViewModel, or is it simply a matter of preference?

Était-ce utile?

La solution

You should use the second ICommand implementation (RelayCommand) as it is the generic Command that you can use for any purpose i.e you can use this command instance to bind to any other button/menu commands. The first one is rather rigid and serves only one purpose.

Ideally every new class should be in a new file. I personally create the Command Folder at ViewModel layer and put Commands over there.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top