简体   繁体   中英

Is there some way to avoid implement ICommand to can use a Button in MVVM?

I am developing a very simple application, a view with few buttons. I would like to can use the click event of the buttons in the view model.

But the I have only found examples that need to use the Interactivity.dll from blend, or I have to implement the ICommand interface or some other solutions.

I would like to know if there are any solution now days that doesn't need to implement ICommand or use frameworks like MVVM Light. I would like to use the most simple solution.

Thanks.

Why do you want to avoid ICommand?

You can write your own implementation of ICommand but this is unnecessary when MVVM Light has all of the tools and is easy to use.

If your app is that simple, your choices are:

  1. Ignore MVVM pattern and just implement event handlers in code behind

  2. (I suggest) Use MVVM Light with the default ICommand implementation

    public RelayCommand ExampleRelayCommand => new RelayCommand(ExampleMethod);

     private void ExampleMethod() { } 
  3. If you want the EventArgs then you can implement interactivity triggers and EventToCommand using PassEventArgsToCommand="True" also using MVVM Light

      public RelayCommand<RoutedEventArgs> EventRelayCommand => new RelayCommand<RoutedEventArgs>(EventRelayCommandMethod); private void EventRelayCommandMethod(RoutedEventArgs e) { } 

Then, inside the button in XAML:

<Button Grid.Column="0" Content="Example"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <command:EventToCommand Command="{Binding EventRelayCommand}" PassEventArgsToCommand="True" /> </i:EventTrigger> </i:Interaction.Triggers> </Button>

Why are you so averse to using ICommand ? If you're going to follow the MVVM pattern, it's the perfect way to achieve separation between the UI and business logic layers.

The most basic implementation of ICommand is just something like this

/// <summary>
/// a very simple ICommand implementation
/// </summary>
public class BasicCommand: ICommand
{
    private readonly Action _execute;

    public BasicCommand(Action execute)
    {
        _execute = execute;
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        _execute?.Invoke();
    }

    public event EventHandler CanExecuteChanged;
}

More advanced implementations of ICommand such as the MVVM-Light RelayCommand one also take care of disabling any bound control (eg button or menu item) as required through the CanExecute mechanism, in a much more decoupled and cleaner way than trying to set Button.InEnabled.

You may want to take a look at Caliburn.Micro . It's a MVVM library that lets you define methods without any commands in your view model and bind to them using naming conventions:

View Model:

public void Click() { /* handle */ }

View:

<Button Content="Click!" x:Name="Click" />

Another option would be to add a click event handler to your view's code-behind class and call a mehod of the view model from there:

private void Button_Click(object sender, RoutedEventArgs e) 
    => (DataContext as GeneralOptionsViewModel).Click();

Then you don't use any commands but you still keep the application logic in the view model.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM