Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I somehow tell Resharper about the type of the ViewModel?

Tags:

c#

resharper

mvvm

We have Views and ViewModels in different assemblies. Views' assembly has the reference to the VMs. (sometimes we need code behind).

ViewModel's DataContext is set in code, not in XAML. Thus nor VS neither Resharper can help as with intellisense and Resharper also gives a lot of warnings.

Is there any directive for Resharper we can set in XAML comments to say that we intend to use the View with VM of a particular type?

Update:

Nice blogpost as addition to the accepted answer.

like image 818
Pavel Voronin Avatar asked Dec 13 '12 15:12

Pavel Voronin


2 Answers

I had the same issue and resolved it by using the design time support in XAML to get intellisense support in the XAML editor which also satisfies Resharper binding validation.

Note the d: namespace used in the code snippet below. This will be ignored at runtime. You can also use a ViewModelLocator which will add design time (Fake) repositories to the IoC container removing any dependencies from external sources like web services or other data sources.

XAML design time support:

<local:ViewBase
    ...
    mc:Ignorable="d" 
    d:DataContext="{Binding Source={d:DesignInstance Type=viewModel:MainViewModel, IsDesignTimeCreatable=True}}">

XAML ViewModelLocator:

<local:ViewBase
    ...
    mc:Ignorable="d" 
    viewModel:ViewModelLocator.ViewModel="MainViewModel" >

ViewModelLocator:

    static ViewModelLocator()
    {
        if (DesignMode.DesignModeEnabled)
        {
            Container.RegisterType<IYourRepository, YourDesignTimeRepository>();
        }
        else
        {
            Container.RegisterType<IYourRepository, YourRuntimeRepository>();
        }

        Container.RegisterType<YourViewModel>();
    }
like image 120
lawrab Avatar answered Sep 23 '22 10:09

lawrab


If you set a ViewModel into the .DataContext property of a UIElement in your XAML as a placeholder, it will be replaced when you set it at runtime via your constructor injected ViewModel.

So you could have

<UserControl.DataContext>
    <Pages:WelcomeLoadingViewModel />
</UserControl.DataContext>

Then in the UserControls constructor have

public WelcomeLoading(WelcomeLoadingViewModel viewModel)
{
   this.DataContext = viewModel;
}

OR

public HomePage()
{
   this.InitializeComponent();

   this.DataContext = ViewModelResolver.Resolve<HomePageViewModel>();

This would mean that you would get Binding and Resharper support as they can reflect the ViewModels from the XAML Datacontext. But also enjoy the benefits of Dependancy Injected ViewModels, as the VM would be replaced at runtime from your DI Container.

like image 44
Patrick McCurley Avatar answered Sep 25 '22 10:09

Patrick McCurley