3
votes

I have a behavior that exposes several command properties. Typically I use MVVM Light and would just use a routed command in my view model and bind to those. However, this project is using Caliburn.Micro so I'm trying to do it the Caliburn.Micro way. Is there some syntax I can use on the Message.Attach to do this (is there any good documentation on the parser for Message.Attach)?

Do I have to modify the behavior to expose events to make this work with Caliburn.Micro?

3
Implement the behavior using a coroutine.Derek Beattie

3 Answers

4
votes

Caliburn.Micro has its own mechanism for view/viewmodel communication as an alternative to commanding called Actions. You should be able to set the Action parameter to be your Execute delegate of your existing command, and if required set the appropriate view control property (e.g. IsEnabled) to bind to your CanExecute delegate.

3
votes

Caliburn.Micro handles routing Actions for your, as long as you setup the View and ViewModel correctly (it uses some implicit assumptions, which may or may not be your cup of tea) Here is a link about Actions: http://caliburnmicro.codeplex.com/wikipage?title=All%20About%20Actions&referringTitle=Documentation

A better, less tightly coupled way, of doing the same thing is to use the Event Aggrigator - http://caliburnmicro.codeplex.com/wikipage?title=The%20Event%20Aggregator&referringTitle=Documentation

Take a look at the HelloEventAggrgator code sample available in the Caliburn.Micro source, for an example... But the basic jist is this:

You make custom events for use by the aggregator.

public YourEvent
{
...
}

Your view will publish those custom events - it does not care who is listening, only that the event gets published.

public YourCodeBehind
{
    public Button_Clicked(...)
    {
        this.Events.Publish(new YourEvent());
        ...
    }
    ....
}

Your ViewModels will be setup to handle those events, by adding IHandle

[Export(typeof(...))]    
public class YourViewModel : IShell, IHandle<YourEvent>
{
    [ImportingConstructor]
    public YourViewModel(IEventAggregator events)
    {
        events.Subscribe(this);
        ...
    }
    public Handle(YourEvent event)
    {
        ...
    }
    ...
{

This method maintains very high SoC, by allowing the View to really only deal with binding to data, and publishing events - the view remains unconcerned about how the events are handled.

Each View Model is then setup to handle the Events by adding an IHandle interface. (Note that you can have many different IHandle interfaces on a single ViewModel) The ViewModel is unconcerned about how the event was raised, only that it was, and that it is the authority on handling that event from the Aggregator.

-2
votes

I ended up rewriting the Behavior as a Trigger instead to handle this.