Silverlight中使用MVVM(3)

  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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章