MVVM是否会停止Visual Studio Designer显示xaml的功能? [英] Does MVVM stop the ability for the Visual Studio Designer to show xaml?

查看:82
本文介绍了MVVM是否会停止Visual Studio Designer显示xaml的功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在程序中注意到,当我进行许多复杂的绑定时,Visual Studio无法正确显示xaml.

I've noticed in my programs when I have alot of complicated bindings going on then visual studio does not show the xaml properly.

MVVM及其众多绑定是否会导致这种情况?在Visual Studio设计器中显示xaml以完全删除绑定的最安全方法是吗?

Does MVVM and its numerous bindings cause this? Is the safest way to show xaml in the visual studio designer to remove bindings completely?

推荐答案

否. MVVM核心原则之一是设计者支持.在Expression Blend设计器(Visual Studio的Resp Blend)工具之后,该原理称为可混合性".请注意,Visual Studio使用相同的设计器.

No. One of the MVVM core principles is designer support. The principle is called "Blendability" after the Expression Blend designer (resp Blend for Visual Studio) tool. Note, that Visual Studio uses the same designer.

借助MVVM,您可以通过对设计时数据进行数据绑定来获得更好的设计时支持.例如,在DataGrid或ListBox中,您可以在设计器中看到数据绑定时实际项目的外观.

With MVVM you can achieve much better design time support by databinding to design time data. For example, you in DataGrid or ListBox you can see in the designer how the actual items looks like when databound.

破坏设计者与绑定的复杂性无关.

您只需要遵循一些简单的原理,并了解设计器中发生的事情.

You just need to follow few simple principles and understand what's going on in the designer.

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

First of all, Visual Studio designer creates instance of the ViewModel in the designer process. You need to be careful, that you don't execute such code in the viewmodel, that could break the designer. Here are some examples:

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

  1. This will break the designer, because Visual Studio Designer is not allowed to do DB calls.

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

在构造函数中调用DB或FileSystem仍然是错误的做法

calling DB, or FileSystem in constuctor is bad practice anyway

这会破坏设计器,因为VS Designer无法访问您的配置

this breaks the designer, because VS Designer does not have access to your configuration

//ctor
public MyViewModel()
{
   string configValue = ConfigurationManager.AppSettings["SomeProperty"]
}

  • 如果您将数据绑定到属性,则将自动执行getter.这段代码破坏了设计器,因为App.Current是Visual Studio设计器,而不是您的应用程序!小心点.

  • if you databind to a property, the getter is acually executed. This code breaks the designer, because App.Current is the Visual Studio Designer, not your app! Be carefull about it.

    public class MyViewModel
    {
       public string SomeProperty
       {
           get { return App.Current.MainWindow.SomeProperty; }
       }
    }
    

  • 绑定到CountOfItems时,这将导致NullReferenceException,因为VS Designer不会调用Load()

  • This will cause NullReferenceException when binding to CountOfItems, because VS Designer doesn't call Load()

    public class MyViewModel
    { 
       private List<string> _items; 
    
       public void Load()
       {
           _items = new List<string>{ "Item1", "Item2" }
       }
    
    
       public int CountOfItems
       {
           get { return _items.Count; }
       }
    }
    

  • 良好做法

    只需检查您是否在需要的设计模式下:

    Good practices

    Just check if you are in the design mode wherever needed:

    //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();
           }
        }
    }
    

    我创建了代码段,在其中使用了这种模式:

    I've created code snippet, where I use this pattern:

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

    我实际上并没有直接实例化ViewModel,但是我注入了ViewTime的DesignTime版本:

    I don't actually instantiace the ViewModel directly, but I inject DesignTime version of the viewmodel:

    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设计器过程中,它将很好地显示有问题的代码行.

    If your designer breaks anyway and you don't know why, you can attach another instance of visual studio to the xaml designer process and it will nicelly show the problematic line of code.

    最后但并非最不重要的是,您可以轻松关闭实例化ViewModel.只需在d:DataContext

    Last, but not least, you can easily turn off instanciating the ViewModels. Just set IsDesignTimeCreatable=false in d:DataContext

    1. 检查可以由xaml执行的viewmodel的所有代码执行路径 设计流程
    2. 请勿在这些执行路径中访问数据库,Web服务或文件系统
    3. 请勿访问静态资源,例如Application.Current,因为thay可能未正确初始化
    4. 检查所有已绑定数据的吸气剂.他们可能会尝试返回设计者未初始化的内容.
    5. 为设计器和运行时执行路径使用分支(例如if..else)
    6. 总是生成一些虚假的设计时数据
    1. Check all the code execution paths of your viewmodel which can be executed by the xaml designer process
    2. Do not access database, webservices or filesystem in those execution paths
    3. Do not access static resource, e.g. Application.Current, because thay may not be initialized properly
    4. Check all getters of properties that are databound. They may trie to return something that was not initialized by the designer.
    5. Use branching (e.g. if..else) for the designer and runtime execution paths
    6. Always generate some fake design-time data

    这篇关于MVVM是否会停止Visual Studio Designer显示xaml的功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆