MVVM Light,Metro App,继承ViewModelBase会破坏设计模式

时间:2013-04-17 20:24:53

标签: xaml mvvm microsoft-metro windows-store-apps mvvm-light

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

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

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

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

我最终将其缩小到我的viewmodel中的继承。我有一个基本的viewmodel,我的所有viewmodel都是从这样声明的继承:

public class BaseViewModel : ViewModelBase
{
}

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

public class MainViewModel : BaseViewModel
{
}

现在,在运行时,一切都运行得很好(这让我感到困惑),但设计模式中断了。

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

public class MainViewModel : ViewModelBase
{
}

我认为代码中的某些东西可能导致了一个问题,所以除了编译所需的内容之外,我对所有内容进行了评论,但仍然收到相同的结果。

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

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

更新 在阅读了LBugnion和Will的评论后,当我注意到我已经忘记在BaseViewModel中忘记注释我的代码时,我正准备调试设计模式。我确实发现那里有破码。设计模式不喜欢以下行:

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

我用它来更新代码中的UI线程。我猜(有更多有经验的人可能会参与其中)在设计模式中没有UI线程吗?

通常我使用“IsInDesignMode”属性来使我的viewmodel几乎不能用于设计,但显然忘了在这里这样做,所以我将上面的行改为

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

我的傻瓜

1 个答案:

答案 0 :(得分:2)

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

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

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

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

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

处理这个的方法是,每当你有可能在设计器中执行的代码时(例如在构造函数中,在属性更改事件处理程序中等),你应该使用DesignerProperties.GetInDesignMode(new DependencyObject())来确定你是否是在执行代码之前设计师保证在设计师中破解。

不幸的是,有时很难确定代码是什么。我对难以推断的失败的唯一解决方案是注意异常类型,启动另一个Visual Studio实例,附加到第一个,然后配置调试以始终为该异常类型中断。

相关问题