I have a ViewModel
that accepts several constructor parameters. As I understand because of this the only way to set View's DataContext is using code behind.
This has its downsides:
- Visual Studio will not show
ViewModel
inteliscence for the view that is being constructed - There is no way to see design time data that is defined in my
ViewModel
constructor in XAML designer because designer simply breaks
What are my options?
I would like to have a ViewModel
that can accept constructor parameters, have design time data and that my Visual Studio inteliscence provide me suggestions about members in my ViewModel
so I could have a good design experience.
PS. I'm using MVVM Toolkit / Windows Community Toolkit from Microsoft, but I would appreciate any answer on how to achieve my end goal. Thank you.
CodePudding user response:
What are my options?
A common approach is to create a separate design time view model class with a parameterless constructor and set the design time data context to this type:
<Window ... d:DataContext="{d:DesignInstance Type=local:DesignTimeViewModel, IsDesignTimeCreatable=True}"
What you shouldn't do is to design your application and define your classes according to how the designer in Visual Studio works.
CodePudding user response:
The cleanest way to assign a view-model with a paramterised constructor as the data context for a view is using the ViewModelLocator
pattern.
public class ViewModelLocator
{
public ViewModelLocator()
{
// define view-model definitions in IoC container.
}
public MainViewModel MainViewModel
{
get
{
// use the appropriate construct for your choice of IoC container
var result = IoCContainer.GetInstance<MainViewModel>();
return result;
}
}
}
An instance of this class can be created in App.xaml
<Application.Resources>
<local:ViewModelLocator x:Key="ViewModelLocator">
</Application.Resources>
which becomes an application wide resource, that can be referenced in each view.
Now we can fetch an instance of a specific view-model at any time, including in the designer, and assign it as the DataContext of the view.
<Window
x:Class="MyApplication.MainView"
...
DataContext="{Binding Source={StaticResource ViewModelLocator}, Path=MainViewModel}" />
For more details on the usage of this ViewModelLocator pattern, including having design-time data in your ViewModel, check out my blog post.