這篇主要引申出Command結合MVVM模式在應用程序中的使用
我們要做出的效果是這樣的
就是提供了一個簡單的查詢功能將結果綁定到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