1

I have to create a WPF application with Caliburn.Micro 2.0.2 for my Bachelor exam.

In this application three different Views will be shown in a single Shell (Window) and they have to communicate with each other. So I need the Event Aggregator. I also need the Window Manager to show additional dialogs.

My actual problem is that I have to bring all this together with full Design Time Support. Unfortunately there is no example for that case.

The documentation of Caliburn.Micro says that a default constructor is needed in the view model, to provide design time support. However the Event Aggregator and the Window Manager are used as constructor parameters in the view model, so there is no default constructor at first.

The documentation also says that in such a case the ViewModelLocator should be used to get Design Time Support. Unfortunately the section about the ViewModelLocator doesn't give me enough information about how to do that.

Another idea might be to chaining constructors like this:

public class ExampleViewModel : PropertyChangedBase
{
    private readonly IEventAggregator eventAggregator;
    private readonly IWindowManager windowManager;

    public ExampleViewModel() : this(null)
    {
    }

    public ExampleViewModel(IEventAggregator eventAggregator) : this(eventAggregator, null)
    {
    }

    public ExampleViewModel(IEventAggregator eventAggregator, IWindowManager windowManager)
    {
        this.eventAggregator = eventAggregator;
        this.windowManager = windowManager;

        // doing everything needed for the Design Time Support
    }
}

But I have no idea if that will work at last.

I hope somebody here can help me with this issue.

1 Answers1

1

You can use a separate DataContext (ViewModel) for design time. You need to add in your XAML where the view model is used:

<UserControl 
    ...
    xmlns:dt="clr-namespace:YourProject.DesignTimeHelpers;assembly=YouAssembly"
    d:DataContext="{Binding Source={x:Static dt:DesignTimeModels.ExampleViewModelForDesignTime}}">

There is the DesignTimeModels static class with the view model:

public static class DesignTimeModels
{
    public static ExampleViewModel ExampleViewModelForDesignTime { get; set; }

    // static constructor
    static DesignTimeModels()
    {
        ExampleViewModelForDesignTime = 
            new ExampleViewModel(new EventAggregator(), new WindowManager());
    }
}

The main idea is creating an instance of the view model by a static initializer with arguments what you need.

If you would like to use a IoC container (Caliburn for example) for instantination of the EventAggregator or the WindowManager, you can use a ServiceLocator pattern. For example:

// static constructor
static DesignTimeModels()
{
    var eventAggregator = ServiceLocator.Get<IEventAggregator>();
    var windowManager = ServiceLocator.Get<IWindowManager>();

    ExampleViewModelForDesignTime = 
        new ExampleViewModel(eventAggregator , windowManager);
}
hcp
  • 3,268
  • 6
  • 26
  • 41
  • @ZaHaDum1984 You are welcome. Please, check the approach and if this post is really usefull, you can mark it as solution of your problem. – hcp Oct 05 '15 at 12:32
  • Unfortunately it doesn't work at last. If I include a view model in the shell as a ContentControl, it is shown if I run the application, but it is NOT shown in the Designer. So this is not finished yet. – ZaHaDum1984 Oct 05 '15 at 13:10
  • @ZaHaDum1984, do you configure the ServiceLocator for your container? – hcp Oct 05 '15 at 13:36
  • Yes, I do. Maybe Property Injection instead of Constructor Injection can solve the problem. I'll try that and report the results here. – ZaHaDum1984 Oct 05 '15 at 14:19
  • @ZaHaDum1984 I explored your project. First of all, content control it is not connected with anything. And blue screen is showed after an application running. Design-time view model work perfectly. It can be checked by an adding something like MainWindowViewModel.WindowTitle = "It's a design mode!" in the DesignTimeModels class. If you have any difficulty with this issue, I can commit example in your repository. – hcp Oct 06 '15 at 06:24
  • My last commit has solved the problem, so it working fine. I just had no time to post that here. Again Thank you for your help. :) – ZaHaDum1984 Oct 06 '15 at 08:27
  • @ZaHaDum1984 I'm happy to help you! :) – hcp Oct 06 '15 at 08:36