0

我有一个奇怪的问题,我似乎找不到任何答案。

我正在通过 NuGet 使用 MVVM Light 使用 Visual Studio 2012 构建 Metro Store 应用程序。

在设计和添加数据上下文 xaml 代码时,studio 给了我一个红色的 swiggly 错误“对象引用未设置为对象的实例”。

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

我终于把它缩小到我的视图模型中的继承。我有一个基本视图模型,我的所有视图模型都继承自声明如下:

public class BaseViewModel : ViewModelBase
{
}

然后显然我所有的视图模型都是这样的:

public class MainViewModel : BaseViewModel
{
}

现在,在运行时一切正常(这让我很困惑),但是设计模式中断了。

但是,如果我删除继承并让我的视图模型直接继承 ViewModelBase,那么在设计模式下一切都很好:

public class MainViewModel : ViewModelBase
{
}

我认为可能是代码中的某些内容导致了问题,因此我将所有内容都注释掉了,除了编译所需的内容并仍然收到相同的结果。

任何人似乎都有这个问题,或者知道我可能做错了什么?在使用 MVVM 处理 Silverlight 或 WPF 应用程序时,我通常使用相同的模式,那里的情况似乎很好。

只是一个旁注,我的 ViewModelLocator 确实有一个 MainVM 属性,它返回 MainViewModel 类。

更新 在阅读了 LBugnion 和 Will 的评论后,我正准备调试设计模式时发现我愚蠢地忘记在 BaseViewModel 中注释掉我的代码。我确实发现那里有破坏代码。设计模式不喜欢下面这行:

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

我用来更新代码中的 UI 线程。我猜(哪个更有经验的人可能会插话)设计模式下没有 UI 线程?

通常我使用“IsInDesignMode”属性使我的视图模型几乎无法用于设计,但显然在这里忘记了这样做,所以我将上面的行更改为

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

我的混蛋

4

1 回答 1

2

一直在发生,主要是因为您的类型中的代码正在设计器中执行。

是的,代码实际上可以在设计器中执行。设计器会将您的程序集加载到设计图面的 AppDomain 中,实例化您的类型,并将该实例用于设计图面。

因此,如果你有这样的事情:

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

它很可能会因为您的数据库不存在而中断,您无法从 app.config 等中找到连接字符串等。

处理这个问题的方法是,只要您有可能在设计器中执行的代码(例如在构造函数中、在属性更改事件处理程序中等),您应该DesignerProperties.GetInDesignMode(new DependencyObject())在执行保证的代码之前确定您是否在设计器中打破设计师。

不幸的是,有时很难确定哪些代码正在破坏。对于难以推断的故障,我唯一的解决方案是记下异常类型,启动另一个 Visual Studio 实例,附加到第一个实例,然后将调试配置为始终中断该异常类型。

于 2013-04-18T14:54:05.653 回答