【干货】个人工作文档节选:XAML MVVM 框架易用性细节优化Tips

1    易用性细节优化

1.1 代码片段

在ViewModel内,会有大量重复性的在Property set中激发 INotifyPropertyChanged.PropertyChanged 事件的代码。 这种属性用已有的代码片段已经很难高效的输入。使用合适的代码片段在VM设计时 不会因为过于机械的修改影响设计思路

1.1.1  Property Code Snippets

在项目模板中加入对应的code snippet

Sample:

键入 propvm [Tab]  [Tab]后 产生如下代码

     

  
private int _PropertyName;
public int PropertyName
{
  get   {     return _PropertyName;   } set   {   _PropertyName=value;   RaisePropertyChanged(()=>PropertyName);   } }

 

 

 

 

1.1.2  Command Code Snippets  

同样作为Command<Object> 的属性 也需要类似的code snippets

Sample:

键入 propcmd[Tab]  [Tab]后 产生如下代码

 

private Command<Object> _CommandName=
    new     Command<Object> (
        p=>{},
        p=>true);
   
public Command< Object > CommandName
{
    get
    {   
        return _CommandName;   
    }   
    set   
    {   
        _CommandName =value;   
        RaisePropertyChanged(()=>CommandName);   
    }
   
}
   
 
          

 

1.2 设计时支持

作为MVVM的UI开发设计基础,一个生产力足够高的框架应当能够为设计时提供VM的结构成员和设计时数据支持。

 

1.2.1  步骤:在设计视图添加设计时VM.

假设我们有一个ViewModel 类型为  My.Project.TestViewModel

在设计器正确引入如下命名空间时

             

   
   

<UserControl
    xmlns:d=”http://schemas.microsoft.com/expression/blend/2008”
    xmlns:vm=”clr-namespace:My.Project”
    …>

   

   

</UserControl>

   

 

   
   

 

在设计器根节点加入

             

   
   

<d:FrameworkElement.DataContext>
        <vm:TestViewModel />

   

</d:FrameworkElement.DataContext>

   

 

   
   

 

这时设计器会为View指定一个TestViewModel的新实例,此时绑定会用这个新实例为模板进行设计时支持,比如所见即所得的绑定结果显示,以及模板设计支持。

对于早期版本的 VS,或者WPF/SL 以外不能支持 blend设计时命名空间的平台,d:DataContext 不被设计时支持, 这时候我们可能需要直接使用 <FrameworkElement.DataContext> 标记。这样做的代价可能是额外产生一个 ViewModel 对象引用。 如果我们能够控制好 ViewModel 默认构造函数中调用的资源,这样做问题并不大,不失为一种办法。

1.2.2  步骤:在VM添加设计时数据与逻辑

由于设计时设计器会创建一个VM实例来帮助设计,VM的设计需要注意以下几点

l  VM要具有默认构造函数,否则设计器无法将其实例化

l  VM中的逻辑要能够判断当前运行环境是否在设计时

n  使用大量珍贵资源的逻辑在设计时不允许运行,比如

u  Timer 逻辑

u  IO操作

 

应当在适当位置添加 “IsInDesignMode” 静态属性,建议在 ViewModelBase中添加。

    

            static bool? _IsInDesignMode;


            /// <summary>
            /// <para>Gets if the code is running in design time. </para>
            /// <para>读取目前是否在设计时状态。</para>
            /// </summary>
            public static bool IsInDesignMode
            {
                get
                {

                    return (
                        _IsInDesignMode
                        ??
                        (

                            _IsInDesignMode =
#if SILVERLIGHT_5||WINDOWS_PHONE_8||WINDOWS_PHONE_7
                                DesignerProperties.IsInDesignTool
#elif NETFX_CORE
                                Windows.ApplicationModel.DesignMode.DesignModeEnabled
#else
                                (bool)System.ComponentModel.DependencyPropertyDescriptor
                                .FromProperty(
                                    DesignerProperties.IsInDesignModeProperty,
                         



typeof(System.Windows.FrameworkElement)) .Metadata .DefaultValue #endif )) .Value; } }

 

      

 

在实现了这个属性之后 在具体Vm的构造函数或Onload事件中用户就可以添加伪数据,也可以避免不能再设计时调用的功能被调用

比如下面这段代码

 

        protected override async Task OnBindedViewLoad(MVVMSidekick.Views.IView view)
        {
            await base.OnBindedViewLoad(view);

            if (IsInDesignMode)
            {
                HelloWorld = "Hello Mvvm world, Design mode sample";
            }
            else
            {
                if (Id == null)
                {
                    Id = Guid.NewGuid().ToString();
                }

                GetValueContainer(x => x.CountDown).GetNullObservable()
                    .Subscribe(
                        _ =>
                        {
                            HelloWorld = string.Format("Loading {0}", CountDown);
                        }
                    );
            }

        }

 

 

 当然, MVVM-Sidekick 这些方面做的都很不错。

posted @ 2013-12-06 11:01  MSFT:waywa 韦恩卑鄙  阅读(1787)  评论(0编辑  收藏  举报