2013-04-17 48 views
0

我有一个奇怪的问题,我似乎无法找到任何答案。MVVM轻,Metro应用程序,继承ViewModelBase打破设计模式

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

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

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

我终于把它缩小到我的viewmodel中的继承。我有一个基础视图模型,我所有的ViewModels继承宣布为:所有我的ViewModels这样

public class BaseViewModel : ViewModelBase 
{ 
} 

那么很明显:现在

public class MainViewModel : BaseViewModel 
{ 
} 

,在运行时的一切工作完全正常(这是混乱我),但设计模式打破了。

但是,如果我删除继承和有我的ViewModels直接继承ViewModelBase,一切都在设计模式罚款:

public class MainViewModel : ViewModelBase 
{ 
} 

我想,也许什么东西在代码中导致一个问题,所以我评论除了编译所需要的东西外,所有的东西都完成了,并且仍然收到相同的结果

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

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

UPDATE 阅读LBugnion和威尔的意见后,我正准备调试设计模式时,我注意到我goofily已经忘记了在BaseViewModel注释掉我的代码。我确实发现那里有破坏代码。设计模式不喜欢以下行:

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

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

通常我使用“IsInDesignMode”属性,以使我的ViewModels几乎非功能性的设计,但显然忘了所以在这里做,所以我改变以上

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

我混日子行

+0

我经常这样做,所以通常这不应该打破设计模式。必须在某个地方抛出异常,你是否尝试调试设计模式代码? – LBugnion

+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实例,附加到第一个,然后将调试配置为始终为该异常类型打破。

+1

给你答案打勾请问因为你给的方法是在这种情况下帮助调试的好方法。如果我还没有发现问题,我肯定会发现使用此解决方案的问题。谢谢! –