gpt4 book ai didi

c# - MVVM 会阻止 Visual Studio Designer 显示 xaml 的能力吗?

转载 作者:太空宇宙 更新时间:2023-11-03 18:23:15 25 4
gpt4 key购买 nike

我注意到在我的程序中,当我进行大量复杂的绑定(bind)时,visual studio 无法正确显示 xaml。

MVVM 及其众多绑定(bind)会导致这种情况吗?在 visual studio 设计器中显示 xaml 以完全删除绑定(bind)的最安全方法是什么?

最佳答案

没有。 MVVM 的核心原则之一是设计师支持。该原理在 Expression Blend 设计器(resp Blend for Visual Studio)工具之后被称为“Blendability”。请注意,Visual Studio 使用相同的设计器。

使用 MVVM,您可以通过数据绑定(bind)到设计时数据来实现更好的设计时支持。例如,您在 DataGrid 或 ListBox 中可以在设计器中看到数据绑定(bind)时实际项目的外观。

破坏设计器与绑定(bind)的复杂性无关

您只需要遵循一些简单的原则并了解设计器中正在发生的事情。

首先,Visual Studio 设计器在设计器进程中创建 ViewModel 的实例。您需要小心,不要在 View 模型中执行此类代码,这可能会破坏设计器。以下是一些示例:

不要这样做

  1. 这会破坏设计器,因为不允许 Visual Studio 设计器进行数据库调用。

    //ctor
    public MyViewModel()
    {
    using(var db = new MyDbContext()} ... //
    }

    在构造函数中调用 DB 或 FileSystem 无论如何都是不好的做法

  2. 这会破坏设计器,因为 VS 设计器无权访问您的配置

    //ctor
    public MyViewModel()
    {
    string configValue = ConfigurationManager.AppSettings["SomeProperty"]
    }
  3. 如果您将数据绑定(bind)到某个属性,则会实际执行 getter。此代码破坏了设计器,因为 App.Current 是 Visual Studio 设计器,而不是您的应用程序!小心点。

    public class MyViewModel
    {
    public string SomeProperty
    {
    get { return App.Current.MainWindow.SomeProperty; }
    }
    }
  4. 这会在绑定(bind)到 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();
}
}
}

我已经创建了代码片段,我在其中使用了这个模式:

d:DataContext="{d:DesignInstance Type=local:MyViewModelDesignTime, IsDesignTimeCreatable=True}"

我实际上并没有直接实例化 ViewModel,而是注入(inject)了 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

重述

  1. 检查您的 View 模型的所有可由xaml 执行的代码执行路径设计过程
  2. 不要访问这些执行路径中的数据库、网络服务或文件系统
  3. 不要访问静态资源,例如Application.Current,因为它们可能没有正确初始化
  4. 检查数据绑定(bind)属性的所有 getter。他们可能会尝试返回设计者未初始化的内容。
  5. 为设计器和运行时执行路径使用分支(例如 if..else)
  6. 总是生成一些虚假的设计时数据

关于c# - MVVM 会阻止 Visual Studio Designer 显示 xaml 的能力吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43640361/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com