MVVMLight ViewModelLocator in UserControl

Is it possible to use MVVMLight ViewModelLocator in UserControl. I added it to my user control in the same way as it is done in MainWindow, but I get an error / popup in VS2010 that says: "Cannot find a resource named Locator. Resource names are case sensitive. "

Has anyone tried this?

The code, which is still the standard MVVMLight WPF starter application ...

Usercontrol

<UserControl x:Class="NavTest3.PersonControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" Height="116" MinWidth="250" Width="300" DataContext="{Binding Person, Source={StaticResource Locator}}" > <!----> <UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Skins/MainSkin.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </UserControl.Resources> 

App.xaml contains ..

 <Application.Resources> <!--Global View Model Locator--> <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" /> </Application.Resources> 

so the problem is with setting "DataContext =" {Binding Person, Source = {StaticResource Locator}} "to userControl."

As already mentioned, this means that every instance of this user control will use the same ViewModel, but I want to start by understanding this problem before moving on.

+3
source share
3 answers

Yes, you can create a static resource in user control

 <UserControl x:Class="MvvmLight1.UserControl1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" xmlns:vm="clr-namespace:MvvmLight1.ViewModel" > <UserControl.Resources> <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" /> </UserControl.Resources> <Grid> </Grid> </UserControl> 

but IMO is not a good idea to use MVVM Light ViewModelLocator for UserControles, because it is a static property, and when you are going to instantiate multiple instances of your user control, they will have the same general ViewModel so that they all work the same way and it's not that what we want for UserControl if you decide to use it once in your entire project.

to get around this problem, you need to change the ViewModelLocator to make all Non static properties, for example:

  public class ViewModelLocator { // v--- You got to comment this out private /*static*/ MainViewModel _main; public ViewModelLocator() { CreateMain(); } public /*static*/ MainViewModel MainStatic { get { if (_main == null) { CreateMain(); } return _main; } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This non-static member is needed for data binding purposes.")] public MainViewModel Main { get { return MainStatic; } } public /*static*/ void ClearMain() { _main.Cleanup(); _main = null; } public /*static*/ void CreateMain() { if (_main == null) { _main = new MainViewModel(); } } public /*static*/ void Cleanup() { ClearMain(); } } 
+3
source

This may be a problem with the order in which resources are loaded ... try assigning the DataContext of the element below in the hierarchy, for example. grid under user control.

 <UserControl x:Class="NavTest3.PersonControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" Height="116" MinWidth="250" Width="300"> <UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Skins/MainSkin.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </UserControl.Resources> <Grid DataContext="{Binding Person, Source={StaticResource Locator}}"> <!-- content --> </Grid> </UserControl> 

Edit :

Try using the data binding in the Visual Studio properties section to establish the binding and confirm that you are seeing Locator. Select the item where your DataContext should go, find the DataContext property and click the property area. Now a dialog box opens in which you can select the locator. Perhaps this solves the problem or helps you find the soul. Also rebuild your project before snapping.

+2
source

Make sure you have no exception in one of your ViewModels. Usually, when I get this error, the locator cannot be created because there is an exception that is thrown by one of the upstream viewsmodel constructs. Can you host your Locator constructor?

if you want to fix this problem yourself, put a breakpoint on your first CreateVM statement in VMLocator and see which VM throws the exception.

0
source

All Articles