现在的位置: 首页 > 综合 > 正文

Silverlight中使用MVVM(3)—进阶

2012年08月26日 ⁄ 综合 ⁄ 共 3723字 ⁄ 字号 评论关闭

转自http://www.cnblogs.com/626498301/archive/2010/08/19/1802974.html

 Silverlight中使用MVVM(1)--基础 

    Silverlight中使用MVVM(2)—提高 

    Silverlight中使用MVVM(3)—进阶 

    Silverlight中使用MVVM(4)—演练

   这篇主要引申出Command结合MVVM模式在应用程序中的使用

    我们要做出的效果是这样的

                      QQ截图未命名

    就是提供了一个简单的查询功能将结果绑定到DataGrid中,在前面的基础上,这个部分相对比较容易实现了

    我们在PageViewModel中添加两个属性

         private string _searchText; 
        //查询关键字 
        public string SearchText 
        { 
            get { return _searchText; } 
            set { _searchText = value; 
            if (PropertyChanged != null) 
            { 
                this.PropertyChanged(this, new PropertyChangedEventArgs("SearchText")); 
            } 
            } 
        } 
        private List<Person> _resultText; 
        //查询结果 
        public List<Person> ResultText 
        { 
            get { return _resultText; } 
            set { _resultText = value; 
            if (PropertyChanged != null) 
            { 
                this.PropertyChanged(this, new PropertyChangedEventArgs("ResultText")); 
            } 
            } 
        }

这两个属性我们后面将绑定到View中,下面实现查询方法

        //查询方法 
        public void Searhing() 
        { 
            List<Person> person = null; 
            if (!string.IsNullOrEmpty(SearchText)) 
            { 
                person = new List<Person>();  
                foreach (Person p in Human) 
                { 
                    if (p.name.Contains(SearchText)) 
                    { 
                        person.Add(p); 
                    } 
                } 
            } 
            if (person != null) 
            { 
                ResultText = person; 
            } 
        }

我们这里就是通过查询到的集合person赋值给查询结果,这两步比较好理解,然后我们需要在ViewModel中声明一个Command对象来执行页面的单击事件

        private ICommand _cmd; 
        //声明Command 
        public ICommand Cmd 
        { 
            get { return _cmd; } 
        } 
        public PageViewModel() 
        { 
            Human = new List<Person>(); 
            Human = new Persons().getPerson(); 
            _cmd = new QueryCommand(this); 
        }

在构造函数中实例了Command对象,在这里我们仍然有一步工作需要完成,就是对QueryCommand的实现

         public class QueryCommand:ICommand 
       { 
        public PageViewModel _pageVM = null; 
        public QueryCommand(PageViewModel vm) 
        { 
            _pageVM = vm; 
        } 
        public bool CanExecute(object parameter) 
        { 
            return true; 
        } 
        public event EventHandler CanExecuteChanged 
        { 
            add { } 
            remove { } 
        } 
        public void Execute(object parameter) 
        { 
            _pageVM.Searhing(); 
        } 
      }

你可以看出来Command类是用ViewModel来实例的,自然这里面由Execute()完成查询这个工作。

最后我们将UI上做点小小的变动

        <data:DataGrid ItemsSource="{Binding ResultText}" Height="200" HorizontalAlignment="Left" Margin="12,88,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="200" /> 
        <TextBox Height="23" Text="{Binding SearchText,Mode=TwoWay}" HorizontalAlignment="Left" Margin="12,46,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" /> 
        <Button Content="查询" Height="23" HorizontalAlignment="Left" Margin="137,46,0,0" Name="btnSearch" VerticalAlignment="Top" Width="75" />

我们将DataGrid的ItemSource属性绑定到ResultText上,对于输入框我们则将其绑定到SearchText属性上,这样我们就完成了大部分的工作

下面就是将View和ViewModel两者之间如何关联了,因为Sl3中不支持Commnad这个属性,所以这里我们就在后台进行声明

        PageViewModel pageviewmodel=new PageViewModel(); 
        public PageView() 
        { 
            InitializeComponent(); 
            this.btnSearch.Click += new RoutedEventHandler(btnSearch_Click); 
            this.DataContext =pageviewmodel; 
        } 
        void btnSearch_Click(object sender, RoutedEventArgs e) 
        { 
            pageviewmodel.SearchText = this.textBox1.Text.Trim(); 
            pageviewmodel.Cmd.Execute(null); 
        }

这一步完成后,我们就实现了开头的功能,这个功能虽然实现了,但是你可能会发现一个问题,我们将Searching()的执行写在了QueryCommand.Execute()中,

在这种情况下我们需要为每一个方法声明一个Command类,自然这不是我们期望做的事情,所以我们下面将这个问题优化一下:

我们先声明一个RelayCommand类

       public class RelayCommand : ICommand 
      { 
        private Action _handler; 
        public RelayCommand(Action handler) 
        { 
            _handler = handler; 
        } 
        private bool _isEnabled; 
        public bool IsEnabled 
        { 
            get { return _isEnabled; } 
            set 
            { 
                if (value != _isEnabled) 
                { 
                    _isEnabled = value; 
                    if (CanExecuteChanged != null) 
                    { 
                        CanExecuteChanged(this, EventArgs.Empty); 
                    } 
                } 
            } 
        } 
        public bool CanExecute(object parameter) 
        { 
            return IsEnabled; 
        } 
        public event EventHandler CanExecuteChanged; 
        public void Execute(object parameter) 
        { 
            _handler(); 
        }

这里RelayCommand类可以作为一个派生类用于与页面Command的实现,那么ViewModel中,我们声明一个ICommand属性

        private readonly ICommand _searchCommand; 
        public ICommand SearchCommand 
        { 
            get { return _searchCommand; } 
        } 

自然我们需要将构造函数变动一下

        public PageViewModel()
        { 
            Human = new List<Person>(); 
            Human = new Persons().getPerson();         
            _searchCommand = new RelayCommand(Searhing) { IsEnabled = true }; 
        }

通过第3行代码,我们其实就是将ViewModel与Command分离了,最后我们将button事件代码修改一下

        void btnSearch_Click(object sender, RoutedEventArgs e)
        { 
            pageviewmodel.SearchText = this.textBox1.Text.Trim(); 
            pageviewmodel.SearchCommand.Execute(null); 
        }

这样的话,看起来似乎优雅了点,关于这部分内容网上资源也比较多,就不多解释了。下篇我将结合MVVM与Command实现一个简单的CRUD操作

 代码下载:CommandInMVVMSL3+VS2010

 

抱歉!评论已关闭.