简体   繁体   中英

WPF set DataContext to a ViewModel without default constructor

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.

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.

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 .

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