MVVM 是不是会停止 Visual Studio 设计器显示 xaml 的能力?
Posted
技术标签:
【中文标题】MVVM 是不是会停止 Visual Studio 设计器显示 xaml 的能力?【英文标题】:Does MVVM stop the ability for the Visual Studio Designer to show xaml?MVVM 是否会停止 Visual Studio 设计器显示 xaml 的能力? 【发布时间】:2017-09-24 05:17:29 【问题描述】:我在我的程序中注意到,当我进行大量复杂绑定时,Visual Studio 无法正确显示 xaml。
MVVM 及其众多绑定是否会导致这种情况?在 Visual Studio 设计器中显示 xaml 以完全删除绑定是最安全的方法吗?
【问题讨论】:
XAML 设计器不能很好地使用 MVVM。但我不会因为头皮发痒就用电锯砍掉我的头。 这与MVVM无关,而是VS中的XAML设计器。 Visual Studio 中的 XAML 设计器和它产生的子进程完全是错误的,并且已经存在了大约 3 年。来自诸如 冻结 VS 之类的烦恼;属性编辑器不起作用。 改用 Expression Blend(如果可以的话)。我从来没有遇到过EB问题 停止使用拖放,只需键入 XAML。它的速度提高了 1000 倍,您可以得到更清晰、更清晰的标记,而且不会很糟糕。 @MickyD:Expression Blend 多年来不存在。现在有 Blend For Visual Studio。但是,Visual Studio 使用与 Blend 相同的 XAML 设计器。那你在说什么? @Liero 借口,借口。当你醒来并发现自己在矩阵中时,你会觉得“这只是文本,我什么都没看到,啊,我刚刚被章鱼机器人杀死了” 【参考方案1】:没有。 MVVM 的核心原则之一是设计者支持。该原理在 Expression Blend 设计器(Resp Blend for Visual Studio)工具之后称为“可混合性”。请注意,Visual Studio 使用相同的设计器。
使用 MVVM,您可以通过数据绑定到设计时数据来获得更好的设计时支持。例如,在 DataGrid 或 ListBox 中,您可以在设计器中看到数据绑定时实际项目的外观。
破坏设计器与绑定的复杂性无关。
您只需要遵循一些简单的原则并了解设计器中发生了什么。
首先,Visual Studio 设计器在设计器进程中创建 ViewModel 的实例。您需要小心,不要在视图模型中执行此类代码,这可能会破坏设计器。以下是一些示例:
不要这样做
这会破坏设计器,因为不允许 Visual Studio 设计器进行 DB 调用。
//ctor
public MyViewModel()
using(var db = new MyDbContext() ... //
在构造函数中调用 DB 或 FileSystem 无论如何都是不好的做法
这会破坏设计器,因为 VS Designer 无权访问您的配置
//ctor
public MyViewModel()
string configValue = ConfigurationManager.AppSettings["SomeProperty"]
如果你数据绑定到一个属性,getter 会被实际执行。此代码破坏了设计器,因为 App.Current 是 Visual Studio 设计器,而不是您的应用程序!小心点。
public class MyViewModel
public string SomeProperty
get return App.Current.MainWindow.SomeProperty;
这会在绑定到 CountOfItems 时引发 NullReferenceException,因为 VS Designer 没有调用 Load()
public class MyViewModel
private List<string> _items;
public void Load()
_items = new List<string> "Item1", "Item2"
public int CountOfItems
get return _items.Count;
良好做法
只要在需要的地方检查你是否处于设计模式:
//ctor
public MyViewModel
bool IsDesignMode => DesignerProperties.GetIsInDesignMode(new DependecyObject());
public MyViewModel()
if (IsDesignMode)
//this will be shown in the designer
Items = new List<string> "Item1", "Item2"
//INotifyPropertyChanged details ommited due to simplification
public List<string> Items get; private set;
public void Load()
//optionally you may check IsDesignMode
using (var db = new MyDbContext())
this.Items = db.Items.Select(i => i.Name).ToList();
我创建了代码 sn-p,我在其中使用了这种模式:
d:DataContext="d:DesignInstance Type=local:MyViewModelDesignTime, IsDesignTimeCreatable=True"
我实际上并没有直接实例化 ViewModel,但我注入了 ViewModel 的 DesignTime 版本:
public class MyViewModel()
protected MyViewModel()
//both runtime and design time logic.
//you may use IsDesignMode check if needed
public MyViewModel(ISomeExternalResource externalResource) : this();
//this is executed only at run time
_externalResource = externalResource;
Items = externalResouce.GetAll();
public List<string> Items get; protected set;
public class MyViewModelDesignTime : MyViewModel
public MyViewModelDesignTime () : base()
//this will be show in the designer
Items = new List<string> "Item1", "Item2" ;
如果您的设计器仍然中断并且您不知道原因,您可以将另一个 Visual Studio 实例附加到 xaml 设计器进程,它会很好地显示有问题的代码行。
最后但同样重要的是,您可以轻松关闭 ViewModel 的实例化。只需在 d:DataContext 中设置IsDesignTimeCreatable=false
回顾
-
检查可以由 xaml 执行的视图模型的所有代码执行路径
设计流程
不要在这些执行路径中访问数据库、Web 服务或文件系统
不要访问静态资源,例如Application.Current,因为可能没有正确初始化
检查所有数据绑定属性的getter。他们可能会尝试返回设计者未初始化的内容。
对设计器和运行时执行路径使用分支(例如 if..else)
总是生成一些虚假的设计时数据
【讨论】:
"最后但同样重要的是,您可以轻松关闭 ViewModel 的实例化。只需在 d:DataContext 中设置 IsDesignTimeCreatable=false"。或者,在 XAML 设计器的工具栏上,选择禁用项目代码按钮 - 来源:docs.microsoft.com/en-us/visualstudio/designers/… @MotKohn:唯一的问题是当设计器失败时按钮通常不可见:) 如果您将Dispatcher
用于async
任务,请注意。除此之外,这是一个很棒的答案!干得好@Liero
非常感谢!我一直在处理这个问题一段时间,最后用谷歌找到了这个答案。【参考方案2】:
是的,如果您的绑定和 Viewmodel 很复杂,那么您的设计时间可能无法正常工作。但是,如果您想要设计时支持,则创建一个虚拟视图模型,您可以将其设置为设计时视图模型,它将仅在设计时使用虚拟视图模型。检查下面的代码。
d:DataContext="d:DesignInstance Type=yourviewmodetype, IsDesignTimeCreatable=True"
【讨论】:
以上是关于MVVM 是不是会停止 Visual Studio 设计器显示 xaml 的能力?的主要内容,如果未能解决你的问题,请参考以下文章
visual studio写完程序,编译以后,再改程序,编译器不编译改过后的程序
Visual Studio 2015 (C++):在第一次构建错误时停止编译(不是第一个项目)
如何在 Visual Studio 中为客户端 MVVM 语言获取 Razor 智能感知?