我不懂MVVM,主要这个名字有点井,不过还是挺感兴趣的,嘿嘿
我之前用WPF写的通讯录,http://nonocast.cn/?p=1870
抛砖引玉,仅供参考,顺便看看MVVM怎么实现
板凳瓜子伺候

解决方案 »

  1.   

    lz还可以加上对 DelegateCommand 和 ReplyCommand 的介绍
      

  2.   

    already ed. I'm gonna study your example after work tonight. Thank you for sharing this!
      

  3.   

    支持楼主~~对于框架来说我最喜欢的是MvvmLight Toolkit,轻巧,无冗余,框架包含的功能都是最常见的,在我每个项目基本都会用到;至于页面导航,MEF等,这些不是必须的,只需在原有框架上面扩展就可以了,最终形成自己的框架;对于prism这种框架,虽然功能全面,但是相对太复杂,学习成本太高,不过可以借鉴其中一些思想和方法,不是必要的话最好还是从最基础框架开始
      

  4.   

    看了lz之前的帖子  支持lz继续发帖 
      

  5.   

    前段时间刚研究了一下MVVM
    总体感觉就是将WPF内数据绑定给独立封装了出来
    只是暂时还不是很理解其中需要继承自 INotifyPropertyChanged接口的目的
    不知楼主是否可以讲解一下?
      

  6.   


    public class MainWindowVM : INotifyPropertyChanged 
        { 
            public MainWindowVM() 
            { 
                Employees = GetEmployeeList(); 
            } 
     
            ObservableCollection<Employee> GetEmployeeList() 
            { 
                ObservableCollection<Employee> employees = new ObservableCollection<Employee>(); 
     
                employees.Add(new Employee { MemberID = 1, Name = "John Hancock", Department = "IT", Phone = "31234743", Email = @"[email protected]", Salary = "3450.44" }); 
                employees.Add(new Employee { MemberID = 2, Name = "Jane Hayes", Department = "Sales", Phone = "31234744", Email = @"[email protected]", Salary = "3700" }); 
                employees.Add(new Employee { MemberID = 3, Name = "Larry Jones", Department = "Marketing", Phone = "31234745", Email = @"[email protected]", Salary = "3000" }); 
                employees.Add(new Employee { MemberID = 4, Name = "Patricia Palce", Department = "Secretary", Phone = "31234746", Email = @"[email protected]", Salary = "2900" }); 
                employees.Add(new Employee { MemberID = 5, Name = "Jean L. Trickard", Department = "Director", Phone = "31234747", Email = @"[email protected]", Salary = "5400" }); 
     
                return employees; 
            } 
     
            private ObservableCollection<Employee> _employees; 
            public ObservableCollection<Employee> Employees 
            { 
                get { return _employees; } 
                set 
                { 
                    _employees = value; 
                    RaiseChange("Employees"); 
                } 
            } 
     
            public event PropertyChangedEventHandler PropertyChanged; 
            public void RaiseChange(string PropertyName) 
            { 
                if (PropertyChanged != null) 
                    PropertyChanged(this, new PropertyChangedEventArgs(PropertyName)); 
            } 
        }
    So, in the viewmodel, we now have a few things added, we might as well try and understand what they do !
     
    First the class name. MainWindowVM : INotifyPropertyChanged
     
    The thing to notice is the 'INotifyPropertyChanged', what this does is inherit the 'INotifyPropertyChanged' interface to the MainWindowVM class. When inheriting this Interface, we now get access to the use of the 'PropertyChangedEventHandler', which we can call at any time we would like to update a public property. This ensures that if the view is binding to that specific public property, it will be updated.
     
    But first we have to make sure we implement that PropertyChanged event! and we do that in the bottom of the class by adding this.
      

  7.   

    回20楼:ObservableCollection已经实现了'INotifyPropertyChanged'接口和'INotifyCollectionPropertyChanged'接口,拿它做示例讲解'INotifyPropertyChanged'的用法不是很合适;另外在构造函数中初始化属性,是可以不用调用RaiseChange的这么说吧,比如有一个普通的集合List<string>保存一个Combobox的值列表,如下示例,CityList是在构造函数中初始化的,Combobox中有值,CityListA和CityListB是模拟异步执行,在构造函数执行完后才初始化的,那么就必须调用RaiseChange通知页面属性已更改,通过示例可以看出来CityListB没有调用RaiseChange集合没有内容,而CityListA是可以显示下拉列表内容的xaml:<Window x:Class="WpfApplication4.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
        <ComboBox Height="23" ItemsSource="{Binding CityList}" HorizontalAlignment="Left" Margin="58,30,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" />
        <ComboBox Height="23" ItemsSource="{Binding CityListA}" HorizontalAlignment="Left" Margin="58,81,0,0" Name="comboBox2" VerticalAlignment="Top" Width="120" />
        <ComboBox Height="23" ItemsSource="{Binding CityListB}" HorizontalAlignment="Left" Margin="58,135,0,0" Name="comboBox3" VerticalAlignment="Top" Width="120" />
      </Grid>
    </Window>
       using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;namespace WpfApplication4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();            this.DataContext = new MainWindowVM();
            }
        }    public class MainWindowVM : System.ComponentModel.INotifyPropertyChanged
        {
            public MainWindowVM() 
            {
                CityList = new List<string> { "武汉", "上海", "深圳", "北京" };            #region 模拟异步加载集合
                System.ComponentModel.BackgroundWorker bw = new System.ComponentModel.BackgroundWorker();
                bw.DoWork += (s, e) =>
                    {
                        System.Threading.Thread.Sleep(1000);
                        CityListA = new List<string> { "南京", "合肥", "重庆"};
                        CityListB = new List<string> { "天津", "大连", "沈阳" };
                    };            bw.RunWorkerCompleted += (s, e) =>
                {
                    RaiseChange("CityListA");
                    RaiseChange("CityListB");
                };            bw.RunWorkerAsync();
                #endregion
            }        public List<string> CityList
            {
                get;
                private set;
            }        public List<string> CityListA
            {
                get;
                private set;
            }        public List<string> CityListB
            {
                get;
                private set;
            }
            public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
            public void RaiseChange(string PropertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(PropertyName));
            }     }}
      

  8.   

    上面示例有点失误,CityListA 和CityListB都调用RaiseChange了,需要将RaiseChange("CityListB");一句注释掉
      

  9.   

    上面示例中需要将RaiseChange("CityListB");一句注释掉,才能看出CityListB和CityListA绑定的区别
      

  10.   

    MVVM如果用一句话来概括(我的理解)就是用属性(property)和界面的元素绑定
      

  11.   

    看了lz之前的帖子 支持lz继续发帖 
      

  12.   

    viewmodel继承了Inotifypropertychanged接口,model中还需要集成这个接口吗?有些教程model也继承了
      

  13.   

    I'll keep updating this.
      

  14.   

    Sorr, in company now so not convenient to input Chinese. From my understanding, INotifyPropertyChanged is a contract between your objects and XAML. When you bind your object to XAML's DataContext as well as some properties, without properly implementing INotifyPropertyChanged, you can't trigger UI refresh in your object (usually view model). You can think in this way: for self-aware refresh, XAML only responds to those "good" view models who have implemented INotifyPropertyChanged interface. Hopefully this can be helpful to you.
      

  15.   

    I'll answer your question tonight after work.
      

  16.   

    呵呵,又来了我来吐槽把,别跟我mvvm了其实你每天都在mvvm,只要你在绑定数据的时候,觉着别扭。所以对数据重整了,其实都是mvvm  包括 list<T>.Select(p=>sex=p.sex==1?"男":"女");  包括 list<T>.select(p=>new 莫个实现了这个界面绑定接口的class(p));  包 ClassA.cast<ClassB>()所以每次看见这些所谓的MVVM我就想笑啊,你平时都做啥了,上面这些数据重整过程你平时没做过??还需要专门跟人讲要MVVM啊,要把Model变成ViewModel啊
      

  17.   


    Dude, it's irrelevant. But anyway, thank you for the reply. I'm not MVVM to you. I'm MVVM to those who're interested. Of course this is not your appetite. So... what can I say
      

  18.   


    Look, I don't really mind if you post some opposite opinions, but what you've posted above is just nonsense (no offence). Can you explain why list<T>.Select(p=>sex=p.sex==1?"男":"女") is MVVM? I don't see any relevance between this code snippet and so-called 'MVVM'. Actually, MVVM is nothing new (data binding has been existing for a long long time in .NET); however, before XAML, it'd never felt so good to use.
      

  19.   

    我刚看了你前面两个帖子看到很多这样的言论“WPF与MVVM” 看到“Winform,asp.net不能MVVM”先说第一条把,其实有关这块内容微软早就出来了,Binding,BingingSource,BingingList<T>,InotifyPorpertyChanged这些玩意打一开始就存在,根本不是现在才出来的东西,早在06年其实就有专门的书籍来讲解了《Windows Forms 2.0数据绑定--.NET智能客户端数据应用程序设计》
     英文原名;Data Binding with Windows Forms 2.0: Programming Smart Client Data 这本书在amazon评级4星半,国内评价比较低只有3星,这本书当年在国内的反响并不好,因为这里有个误区,大多数人认为,这块内容就是给强类型数据集用地,就是给微软自己的sqlDatasource打广告滴。其实作者的本意实际恰恰就是你们号称的MVVM,打造自己的场合性打智能化的数据绑定过程。所以你们把“WPF和MVVM”强挂起来的观念就不存在了
    ==============================在来说第二条,有关asp.net里面不能MVVM,我们都知道treeview和meun菜单都可以支持sitemap和xml数据,可以直接绑定数据源。但是我们在绑定自己的数据源的时候,却不行。微软会告诉你没有实现一个带层级数据接口的数据源。那么如果说们在对外提供这些场合性数据源的时候,能不能把数据重整一下直接实现这个接口,让treeview自己绑定以避免让程序员去递归实现?这完全可以做到。所以所谓的asp.net没有MVVM的言论也不存在了
      

  20.   


    Forget about my previous posts... I didn't have a good attitude to accept the different opinions in those, which is my fault. I never said MVVM ONLY works with WPF, please refer to this: "我还是以WPF+MVVM的本地桌面程序为背景,这样一来我们可以不去操心服务器那部分的事情,更加专注我们的MVVM". I post this stuff for free because many people are keen to learn WPF, and MVVM is not a bad start for learning that.By the way, I don't work on ASP.NET. When it comes to web application, I love using simple PHP or Silverlight.I said MVVM is just a thought, and you also can apply it in Winform, but usually we use the word MVP (Model-View-Presentation). For asp.net, isn't that we have MVC?
      

  21.   


    As for this (what you said): "所以你们把“WPF和MVVM”强挂起来的观念就不存在了", I don't think I did this... But honestly, WPF or Silverlight works very well with MVVM, which I don't think we should deny?
      

  22.   


    And in fact, I don't understand your point. What's the harm to you if I'm here to teach MVVM to those interested guys. If you think MVVM is too shitty to be told, then I'll probably need to change the title of this post to 'M***, not a bad way for WPF starters'? Pal, it's true that you're free to speak anything (not entirely in China though) on internet, but I'm just unable to comprehend why you're here, in this post??
      

  23.   

    我们之所以出来说只是澄清一下“MVVM”并不是一个特别特别需要大做文章的东西在很多年以前,程序员们其实就已经在使用这套东西了Binding b=new Binding("Text",datasource,"xxx")
    b.Parse+=xxx
    b.Format+=xxxx这样的代码在10年的winform程序员界就已经这么做了。同样把数据重整这块东西我们一样在做。这坛子里有人自己搞了一个Itreeview接口,然后在自己的数据绑定前,临时转换为一个实现了Itreeview接口的对象列表,这种手段同样也是一个十分普遍化的操作当然我也承认,在很多不是很明白Bind过程的人手上,他们不会使用Bindingsource,binding这些东西,而是在各个事件里手动处理这个过程,微软现在只是强烈建议使用Binding过程来标准化这样的操作。也就如此而已。
      

  24.   


    I agree with you on this point. MVVM is just a fancy name for old school way of data binding, yet it's not a bad idea to learn this, simply because there are many great frameworks for MVVM that help developers be much more productive. I still need to say: there are many new stuffs in MVVM, maybe not the thought, but the approaches. I see some developers still developing WPF in heavy event-driven way, and that's why I posted this.
      

  25.   

    I've known that this.Lord treat different opinion is so DOOG attitude
      

  26.   

    Do you think that other people is Sarpi?
    you have been the greatest one!
      

  27.   


    的确你说的绑定这些winform和asp.net都有,而且我们都用过,但是,WPF/SL中数据绑定对于模板化的控件来说有着更多的意义,比如你在ListBox控件的ItemTemplate模板中加入了一个可折叠控件Expander,而同时Expander控件中包含一个Datagrid,如果这时你需要查找ListBox中某一条记录,然后判断Expander是否展开,如果展开然后查找Datagrid中某一行记录某一行单元格,将该单元格背景设置为红色;显然Winform中绑定是不能完成这个功能的,而需要遍历查找控件来实现;WPF完全可以通过绑定来实现,因为不光是数据源可以绑定,控件的属性也可以绑定,甚至事件也可以Command绑定,这样对ViewModel中数据的操作就跟操作控件一样,从而达到界面设计和后台代码的分离
      

  28.   


    正所谓存在即合理,Codeplex上那么多Mvvm开源框架,包括msdn也有专门的Prism专题,不是大家都吃饱了撑着才来搞这个的,别人分享点东西又不是什么坏事,用不着这样
      

  29.   

    既然是MVVM,就可以应用在任何地方,不管他是winform还是asp.net,
    MVC中叫做:CreateView,UpdateView和UpdateModel,
    是控制器的职责
      

  30.   


    Winform和asp.net的绑定跟wpf/sl还是有本质区别的,Winform再怎么设计,他必须有后台设计代码,因为winform无法对控件属性进行直接绑定的,要设置控件属性必须首先得到控件引用,而在wpf/sl中是可以不需要获得控件引用,通过绑定就可以实现了,因此ViewModel中可以不用关心操作界面的哪个控件的哪个属性,而只要操作ViewModel的属性的属性就可以了