MVVM Light, приложение Metro, наследование ViewModelBase нарушает режим проектирования

У меня странная проблема, и я не могу найти ответы на нее.

Я создаю приложение Metro Store с Visual Studio 2012, используя MVVM Light через NuGet.

При разработке и добавлении xaml-кода контекста данных студия выдает мне красный глоток с ошибкой «Ссылка на объект не установлена ​​на экземпляр объекта».

DataContext={Binding MainVM, Source={StaticResource Locator}}

В конце концов я сузил его до наследования в моей модели просмотра. У меня есть базовая модель представления, которую все мои модели представления наследуют от объявленной как таковой:

public class BaseViewModel : ViewModelBase
{
}

Тогда, очевидно, все мои модели просмотра как таковые:

public class MainViewModel : BaseViewModel
{
}

Теперь во время выполнения все работает отлично (что меня сбивает с толку), но режим разработки не работает.

Однако, если я удалю наследование и мои модели представления будут напрямую наследовать ViewModelBase, все будет хорошо в режиме дизайна:

public class MainViewModel : ViewModelBase
{
}

Я подумал, что, возможно, что-то в коде вызывает проблему, поэтому я закомментировал все, кроме того, что требовалось для компиляции и получения того же результата.

Кажется, у кого-то есть эта проблема или знает, что я делаю неправильно? Обычно я использую этот же шаблон при работе с приложениями Silverlight или WPF с использованием MVVM, и там все выглядит нормально.

Кстати, у моего ViewModelLocator есть свойство MainVM, которое возвращает класс MainViewModel.

ОБНОВЛЕНИЕ. Прочитав комментарии LBugnion и Уилла, я готовился к отладке режима дизайна, когда заметил, что по глупости забыл прокомментировать свой код в BaseViewModel. Я обнаружил, что там был код взлома. Режиму проектирования не понравилась следующая строчка:

private CoreDispatcher UIDispatcher = Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher;

Который я использовал для обновления потока пользовательского интерфейса в коде. Я предполагаю (кто-то более опытный может вмешаться) в режиме дизайна нет потока пользовательского интерфейса?

Обычно я использую свойство «IsInDesignMode», чтобы мои модели просмотра были практически нефункциональными для дизайна, но, видимо, я забыл сделать это здесь, поэтому я изменил строку выше на

private CoreDispatcher UIDispatcher = IsInDesignModeStatic ? null : Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher;

Мой лох


person Esteban Martinez    schedule 17.04.2013    source источник
comment
Я делаю это регулярно, поэтому обычно это само по себе не должно нарушать режим проектирования. Должно быть где-то возникло исключение, вы пытались отладить код режима разработки?   -  person LBugnion    schedule 18.04.2013
comment
Да, именно так, я обычно делаю то же самое и с другими технологиями, поэтому я подумал, что это могло быть что-то из Metro. По-видимому, я был неправ и допустил ошибку при отладке (как указано в обновлении выше), так что, к счастью, теперь все работает нормально. Спасибо!   -  person Esteban Martinez    schedule 18.04.2013


Ответы (1)


Происходит постоянно, в основном потому, что код ваших типов выполняется в дизайнере.

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

Следовательно, если у вас есть что-то вроде этого:

public MyView : UIElement
{
    public MyView()
    {
        InitializeComponent();
        var database = GetDatabaseObject();
        database.OpenLikeWeAreInProduction();
        FillTheUiLol(database.GetAllKindsOfCrap());
    }
}

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

Способ справиться с этим заключается в том, что всякий раз, когда у вас есть код, который может выполняться в конструкторе (например, в конструкторах, в обработчиках событий изменения свойств и т. Д.), Вы должны использовать _ 2_, чтобы определить, находитесь ли вы в конструкторе, перед выполнением кода, который гарантированно нарушит работу конструктора.

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

person Community    schedule 18.04.2013
comment
Ставим вам галочку ответа Will, потому что указанный вами метод - отличный способ помочь в отладке в этом сценарии. Я уверен, что нашел бы проблему с помощью этого решения, если бы еще не нашел ее. Спасибо! - person Esteban Martinez; 18.04.2013