views:

274

answers:

3

Hello everybody,

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.

A: 

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.

Chris Koenig
This is done. I used the mvvm light toolkit and everything was wired up correctly. as mentioned, it works during runtime. the error only exists during design time. i will post code on monday when i am back in my office
obivandamme
+1  A: 

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

Veer
Thank you for your help, but it is still not working. I added the resource to the view, where i want to add the custom user control and the error is still there. Do i have to change something else?Edit: It works now, by adding the locator as local resource to the window and the user control and by removing it from app.xaml. I think this is ok for design time and since it is solved in blend 4 i can live with that. Thanks
obivandamme
@veer - i'm pretty sure it isn't resolved in Blend 4. is there some other clever trick?
Simon_Weaver
@Simon_Weaver: seems to be not as you said. But works fine with vs. am designing with both now:(
Veer
@veer - are you using any user controls that refer to StaticResources? these are the ones i'm having problems with in Blend 4 - even if those resources are listed in the Resources tab it still cannot resolve them when they are used in a usercontrol and i am trying to display that usercontrol in a parent control within blend
Simon_Weaver
+1  A: 

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);
     }
Simon_Weaver