i am using the mvvm light toolkit to create a WPF application. I created a user control and a corresponding ViewModel. I created a ViewModel property in the ViewModelLocator. I bound the user controls datacontext to the property in the Locator class. When i edit the User Control in Blend or the VS Designer everything seems to work, since i can see my design time data.
When i now try to use my user control on the main window, which is created by the wpf template of the toolkit i receive the error "Resource with the name {Locator} cannot be found" and the row with my user control in the mainwindow.xaml is marked with a red line in Blend. In Visual Studio the same line is marked with the error: "Cannot create an instance of type MyView".
Edit:
This is the source code of the app.xaml
<Application.Resources>
<!--Global View Model Locator-->
<vm:ViewModelLocator x:Key="Locator"
d:IsDataSource="True">
</Application.Resources>
This is the code of the EditCustomerView.xaml
<UserControl.DataContext>
<Binding Path="EditCustomer" Source="{StaticResource Locator}" />
</UserControl.DataContext>
This is the code in my main Window
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Window.DataContext>
<Binding Path="Main" Source="{StaticResource Locator}"/>
</Window.DataContext>
<Grid x:Name="LayoutRoot" Background="{DynamicResource BasicBackground}">
<Grid.RowDefinitions>
<RowDefinition Height="0.927*"/>
<RowDefinition Height="0.073*"/>
</Grid.RowDefinitions>
<ListBox Margin="4" SelectedItem="{Binding Main.SelectedCustomer, Mode=Default, Source={StaticResource Locator}}" ItemTemplate="{DynamicResource CustomerTemplate}" ItemsSource="{Binding Customers, Mode=Default}"/>
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Width="75" Content="Edit" Grid.Row="1" Command="{Binding EditCustomerCommand, Mode=Default}"/>
<Border x:Name="border" Opacity="0.75" Grid.RowSpan="2" Background="#FF706F6F" BorderBrush="Black" BorderThickness="1" Visibility="{Binding EditViewVisibility, Mode=Default}">
<views:EditCustomerView HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>
The application compiles and runs. The error is only occuring during design time.
Can you tell me what i am doing wrong?
Thank you in advance.
This is a known issue. Blend for some reason doesn't recognize the static global resource.
As a workaround you can create a local resource of ViewModelLocator in your Views.
<Window.Resources>
<vm:ViewModelLocator x:Key="Locator"
d:IsDataSource="True">
</Window.Resources>
You have to include the ViewModel namespace.
The issue is reported in codeplex here
and in stackoverflow here
Seems it is resolved in Blend 4
I've come up with a pretty nice workaround to this problem since it doesn't appear to have been fixed in Blend 4:
In the constructor for your XAML UserControl just add the resources it needs, provided you're in design mode within Blend :
public partial class OrdersControl : UserControl
{
public OrdersControl()
{
// MUST do this BEFORE InitializeComponent()
if (DesignerProperties.GetIsInDesignMode(this))
{
if (AppDomain.CurrentDomain.BaseDirectory.Contains("Blend 4"))
{
// load styles resources
ResourceDictionary rd = new ResourceDictionary();
rd.Source = new Uri(System.IO.Path.Combine(Environment.CurrentDirectory, "Resources/Styles.xaml"), UriKind.Absolute);
Resources.MergedDictionaries.Add(rd);
// load any other resources this control needs such as Converters
Resources.Add("booleanNOTConverter", new BooleanNOTConverter());
}
}
// initialize component
this.InitializeComponent();
}
There may be some edge cases, but its working OK for me in the simple cases where before I'd get a big red error symbol. I'd LOVE to see suggestions on how to better solve this problem, but this at least allows me to animate user controls that otherwise are appearing as errors.
You could also extract out the creation of resources to App.xaml.cs
:
internal static void CreateStaticResourcesForDesigner(Control element)
{
if (AppDomain.CurrentDomain.BaseDirectory.Contains("Blend 4"))
{
// load styles resources
ResourceDictionary rd = new ResourceDictionary();
rd.Source = new Uri(System.IO.Path.Combine(Environment.CurrentDirectory, "Resources/Styles.xaml"), UriKind.Absolute);
element.Resources.MergedDictionaries.Add(rd);
// load any other resources this control needs
element.Resources.Add("booleanNOTConverter", new BooleanNOTConverter());
}
}
and then in the control do this BEFORE InitializeComponent():
// create local resources
if (DesignerProperties.GetIsInDesignMode(this))
{
App.CreateStaticResourcesForDesigner(this);
}
This is hard to diagnose without seeing the code, but let me take a stab at it anyway.
It sounds like the problem is the wiring up of your Locator. Make sure you have the following code in your App.xaml
<Application.Resources>
<local:NameOfMyViewModelLocatorClass x:Key="Locator" />
</Application.Resources>
This should wire everything together.
Well to remove the issue even at design time you need to include the following condition in the constructor of ViewModelLocator:
if (ViewModelBase.IsInDesignModeStatic)
{
}
else
{
//Include function to create ViewModel here like the following
CreateMain();
}
Hopefully this would resolve the issue.