«Ресурс с именем {Locator} не найден» Ошибка при использовании пользовательского элемента управления mvvm-light - PullRequest
3 голосов
/ 23 июля 2010

Я использую легкий инструментарий mvvm для создания приложения WPF. Я создал пользовательский элемент управления и соответствующую ViewModel. Я создал свойство ViewModel в ViewModelLocator. Я связал пользовательский элемент управления datacontext со свойством в классе Locator. Когда я редактирую пользовательский элемент управления в Blend или VS Designer, кажется, что все работает, так как я вижу свои данные времени разработки.

Когда я сейчас пытаюсь использовать свой пользовательский элемент управления в главном окне, которое создается шаблоном wpf инструментария, я получаю сообщение об ошибке «Ресурс с именем {Locator} не может быть найден» и строка с моим пользовательским элементом управления в mainwindow.xaml помечается красной линией в Blend. В Visual Studio эта же строка помечена ошибкой: «Не удается создать экземпляр типа MyView».

Edit: Это исходный код приложения. 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 ]

3 голосов
/ 27 июля 2010

Это известная проблема. По какой-то причине Blend не распознает статический глобальный ресурс.

В качестве обходного пути вы можете создать локальный ресурс ViewModelLocator в ваших представлениях.

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

Вы должны включить пространство имен ViewModel.

О проблеме сообщается в кодекплексе здесь

и здесь в стеке

Кажется, это разрешено в Blend 4

3 голосов
/ 26 августа 2010

Я нашел довольно хороший обходной путь для этой проблемы, поскольку она, кажется, не была исправлена ​​в Blend 4:

В конструкторе для вашего пользовательского элемента управления XAML просто добавьте необходимые ресурсы,при условии, что вы находитесь в режиме разработки в 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();

}

Могут быть некоторые крайние случаи, но для меня это работает нормально в тех простых случаях, когда раньше я получал большой красный символ ошибки.Мне очень хотелось бы увидеть предложения о том, как лучше решить эту проблему, но это по крайней мере позволяет мне анимировать пользовательские элементы управления, которые в противном случае выглядят как ошибки.

Вы также можете извлечь создание ресурсов для * 1008.*:

    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);
     }
0 голосов
/ 13 мая 2011

Хорошо, чтобы удалить проблему даже во время разработки, вам нужно включить следующее условие в конструктор ViewModelLocator:

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

Надеюсь, это решит проблему.

0 голосов
/ 24 июля 2010

Это трудно диагностировать, не видя код, но все равно позвольте мне попробовать его.

Похоже, проблема в подключении вашего локатора.Убедитесь, что у вас есть следующий код в вашем App.xaml

<Application.Resources>
    <local:NameOfMyViewModelLocatorClass x:Key="Locator" />
</Application.Resources>

Это должно соединить все вместе.

...