“无法找到名称为{Locator}的资源”使用mvvm-light用户控件时出错

时间:2010-07-23 12:01:24

标签: wpf mvvm mvvm-light

我正在使用mvvm light工具包来创建WPF应用程序。我创建了一个用户控件和一个相应的ViewModel。我在ViewModelLocator中创建了一个ViewModel属性。我将用户控件datacontext绑定到Locator类中的属性。当我在Blend或VS Designer中编辑用户控件时,一切似乎都有效,因为我可以看到我的设计时数据。

当我现在尝试在主窗口上使用我的用户控件时,这是由工具包的wpf模板创建的,我收到错误“无法找到名称为{Locator}的资源”和我的用户控件的行在mainwindow.xaml中,Blend中标有红线。在Visual Studio中,同一行标有错误:“无法创建MyView类型的实例”。

编辑: 这是app.xaml的源代码

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

这是EditCustomerView.xaml的代码

<UserControl.DataContext>
    <Binding Path="EditCustomer" Source="{StaticResource Locator}" />
</UserControl.DataContext>

这是我主窗口中的代码

<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>

应用程序编译并运行。该错误仅在设计时发生。

你能告诉我我做错了吗?

提前谢谢。

4 个答案:

答案 0 :(得分:3)

这是一个已知问题。由于某种原因,Blend无法识别静态全局资源。

作为一种解决方法,您可以在视图中创建ViewModelLocator的本地资源。

<Window.Resources>
    <vm:ViewModelLocator x:Key="Locator" 
                         d:IsDataSource="True"> 
</Window.Resources>

您必须包含ViewModel命名空间。

The issue is reported in codeplex here

and in stackoverflow here

似乎在Blend 4中解决了

答案 1 :(得分:3)

我已经为这个问题提出了一个非常好的解决方法,因为它似乎没有在Blend 4中修复:

在XAML UserControl的构造函数中,只需添加所需的资源,前提是您在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();

}

可能会有一些边缘情况,但在我得到一个大的红色错误符号之前的简单情况下它对我来说还可以。我很乐意看到有关如何更好地解决此问题的建议,但这至少允许我设置用户控件的动画,否则这些控件会显示为错误。

您还可以将资源的创建提取到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());
        }
    }

然后在控件中执行此操作:在InitializeComponent():

之前
     // create local resources
     if (DesignerProperties.GetIsInDesignMode(this))
     {
         App.CreateStaticResourcesForDesigner(this);
     }

答案 2 :(得分:0)

答案 3 :(得分:-1)

即使在设计时也要删除问题,您需要在ViewModelLocator的构造函数中包含以下条件:

if (ViewModelBase.IsInDesignModeStatic)
{
}
else
{
    //Include function to create ViewModel here like the following
    CreateMain();
}

希望这可以解决问题。