• MVVM


      对于.NET平台的开发人员,托微软的福分我们拥有一种更为强大的模型---MVVM。这应该算是做WPF/Silverlight应用的人必懂的一种结构,WPF/silverlight天生支持数据绑定和命令绑定(不过sl在命令绑定上还比较弱),这就为我们使用MVVM创造了可能。

      

      View是什么呢,纯的View只有xaml或者附带必要的只与View本身相关逻辑代码。ViewModel,你可以把它理解为View具体呈现内容所依赖数据的一个抽象,在MVVM中View与ViewModel总会有一种绑定关系,一旦ViewModel中被绑定的数据发生改变View上的数据就会跟着变,相反也有可能,比如你的账号密码框内容发生变化,关联的ViewModel中的数据就会被框架自动通知到。

      在wpf/silverlight中,绑定是通过xaml语法来完成(虽然你可以选择用c#来写但不符合mvvm的宗旨),并且绑定双方的通知机制是有框架来完成,也就是说一个会xaml和blend的美工只需事先和coder商量下“咱们的xx和xx是在哪个ViewModel上叫XXX的属性的XXX属性……”问题之后就可以各干各的了。那么ViewModel怎么写,咋view中又怎么绑定到viewmodel呢?首先我们谈ViewModel。

      说道ViewModel你需要知道依赖属性和依赖对象的概念,这是wpf/silverlight的基础所以不多说。有两种方式写ViewModel。第一种是自己去实现INotifyPropertyChanged接口,并在属性变化时去调用NotifyPropertyChanged事件。

      为了方便我们定义一个ViewModelBase的抽象基类,然后让其他ViewModel继承这个基类。

      public abstract class ViewModelBase : System.ComponentModel.INotifyPropertyChanged, IDisposable   
        {   
            public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;   
            protected void OnPropertyChanged(string propertyName)   
            {   
                if (PropertyChanged != null)   
                {   
          var arg = new System.ComponentModel.PropertyChangedEventArgs(propertyName);   
                    PropertyChanged(this, arg);   
                }   
            }   
            public virtual void Dispose()   
            {   
                 
            }   
        } 
    public class DemoViewModel : ViewModelBase     
    {          
      #region fields          
      private string _propertyA;          
      #endregion          
      #region presentation properties          
      public string PropertyA          
      {              
        get  { return _propertyA; }              
        set        
           {                  
          if (_propertyA != value)                
          {                      
            _propertyA = value;                   
            base.OnPropertyChanged("PropertyA");             
            }         
           }        
      }
    #endregion
    }

    第二种是利用DependencyObject和DependencyProperty。

    using System;
    using System.Windows;
    using System.ComponentModel;
    
    namespace FCClient.AppCode
    {
        public class PeopleItemViewModel : DependencyObject, IPeopleItemViewModel
        {
            public PeopleItemViewModel()
            {
    
            }
            public static readonly DependencyProperty SimpleUserDataProperty 
          = DependencyProperty.Register("SimpleUserData", typeof(SimpleUserData), typeof(PeopleItemViewModel)); public static readonly DependencyProperty RelativeSimpleUserDataProperty
          = DependencyProperty.Register("RelativeSimpleUserData", typeof(ObservableCollection<SimpleUserData>), typeof(PeopleItemViewModel)); public static readonly DependencyProperty AllSimpleUserDataProperty
          = DependencyProperty.Register("AllSimpleUserData", typeof(ObservableCollection<SimpleUserData>), typeof(PeopleItemViewModel)); public SimpleUserData SimpleUserData { get { return (SimpleUserData)base.GetValue(SimpleUserDataProperty); } set { if (!base.CheckAccess()) { Dispatcher.Invoke(new Action( () => { SimpleUserData = value; })); } else base.SetValue(SimpleUserDataProperty, value); } } public ObservableCollection<SimpleUserData> RelativeSimpleUserData { get { return (ObservableCollection<SimpleUserData>)base.GetValue(RelativeSimpleUserDataProperty); } set { if (!base.CheckAccess()) { Dispatcher.Invoke(new Action( () => { RelativeSimpleUserData = value; })); } else { base.SetValue(RelativeSimpleUserDataProperty, value); var collectionView = CollectionViewSource.GetDefaultView(value); collectionView.SortDescriptions.Add(new SortDescription("Distance", ListSortDirection.Ascending)); } } } public ObservableCollection<SimpleUserData> AllSimpleUserData { get { return (ObservableCollection<SimpleUserData>)base.GetValue(AllSimpleUserDataProperty); } set { if (!base.CheckAccess()) { Dispatcher.Invoke(new Action( () => { AllSimpleUserData = value; })); } else { base.SetValue(AllSimpleUserDataProperty, value); var collectionView = CollectionViewSource.GetDefaultView(value); collectionView.SortDescriptions.Add(new SortDescription("Distance", ListSortDirection.Ascending)); } } } } }

    在View中绑定ViewModel。

    为了方便,我们可以在app.xaml中将需要的viewmode放到全局资源字典中。

    image

    然后再我们的vs视图设计器Properties(中文版显示的是“属性”)页上选择为绑定源设置绑定目标(包括source和path等)以及必要的值转换器等等即可。

    image image image

  • 相关阅读:
    linux之scp
    Supervisor之浅谈
    Linux 命令之 2>&1 &
    python多线程实现异步
    python之多进程demo1
    二分查找(python)
    awk命令之小结1
    修改文件权限之chmod
    处理日期数据
    stack unstack pivot 数据的透视
  • 原文地址:https://www.cnblogs.com/xinaixia/p/5774164.html
Copyright © 2020-2023  润新知