2

Currently studying Catel.

In the PersonApplication of the Catel.Examples - specifically, the PersonWindow.xaml: the design time data is not being shown within the Visual Studio Designer.

In the code of the PersonViewModel, the public properties are commented out. Apparently this is because the code is using Fody to create the Model properties at runtime. So, I uncommented the public properties assuming that the Visual Studio Designer requires Public Properties to show designtime data in the Designer. Still, the designtime data of the DesignPersonViewModel does not show in the designer.

The application runs correctly at runtime. There are no messages on Building to indicate an issue within the XAML or the code. The XAML code declaring the designtime datacontext is correct:

d:DataContext="{d:DesignInstance ViewModels:DesignPersonViewModel,
                                 IsDesignTimeCreatable=True}"

Any explanation for why the designtime data does not show in the Designer?

I am using Visual Studio 2015.

Julio Nobre
  • 4,196
  • 3
  • 46
  • 49

2 Answers2

1

Nonetheless my strong appreciation on Catel's framework, I have also witnessed this odd behaviour

It seems that dependency properties are not wired to [Model] decorated property. However, while it should be fixed, you may workaround setting dependency properties directly.

public PersonViewModel(Person person) // this approach works
{
    // Person = person ?? new Person();
    // The following 2 lines provide DesignTime data
    SetValue("FirstName", "Joe");
    SetValue("LastName", "Dalton");
    GenerateData = new Command<object, object>(OnGenerateDataExecute, OnGenerateDataCanExecute);
    ToggleCustomError = new Command<object>(OnToggleCustomErrorExecute);
}

public PersonViewModel(Person person) // this approach does not work
{
    // Person = person ?? new Person();
    Person = new Person() { FirstName = "Joe", LastName = "Dalton" };
    GenerateData = new Command<object, object>(OnGenerateDataExecute, OnGenerateDataCanExecute);
    ToggleCustomError = new Command<object>(OnToggleCustomErrorExecute);
}
Julio Nobre
  • 4,196
  • 3
  • 46
  • 49
  • 1
    Very good. That worked. I wonder why Geert doesn't fix that code. Really impressed with Catel though. But, it is a fairly steel learning curve - still worth it given it's capabilities. Thanks, Julio. – Wayne McKittrick Dec 07 '16 at 09:07
1

The 2nd example requires the view models to invoke much more logic (model to view model mappings). The reason is that you expect the design time view models to automatically do model mappings in design time. Although we could implement it, it wouldn't make much sense.

Design time view models should be very lightweight and simple view models just to show some dummy data inside a designer. They shouldn't behave as fully functioning view models at runtime because it will slow down the designer and could crash the designer in case of exceptions.

From the top of my head, we even check if we are running in a designer and skip quite some logic if so.

So although this looks like a bug, it's by design because design-time view models should be simple and light. We suggest that for design purposes you create a very simple one and add an additional naming convention to the ViewModelLocator. For example:

if (CatelEnvironment.IsInDesignMode)
{
    var viewModelLocator = ServiceLocator.Default.ResolveType<IViewModelLocator>();
    viewModelLocator.NamingConventions.Insert(0, "[UP].ViewModels.[VW]DesignTimeViewModel")
}

This will allow your app to prefer MyPersonDesignTimeViewModel in design mode, but will still load the actual view models when the app is running.

Note that this only works if the views will actually try to resolve the view models at design time, I don't know that from the top of my head because I never use design time.

Geert van Horrik
  • 5,689
  • 1
  • 18
  • 32