WPF中的MVVM模式简单实现
Posted zaranet
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF中的MVVM模式简单实现相关的知识,希望对你有一定的参考价值。
前言:在之前实现WPF程序时,我们可能会把所有的后台逻辑都放在视图的后台文件中,这样的实现方式的好处更直观,方便,对于一些小的应用程序这样做当然没什么问题,但是对于复杂的应用程序这样写的话,可能会导致后台代码显得非常臃肿,到最好变得难以维护。此时想到的解决方案就是职责分离,使后台的逻辑分离到其他类中,MVVM其实我理解就是达到这个目的。下面我们按照MVVM的组成部分来实现下这个MVVM程序。
public class Person { public string Name { get; set; } public int Age { get; set; } }
为了进行测试,下面创建一个静态方法来获得测试数据。
public class PersonDataHelper { public static ObservableCollection<Person> GetPersons() { ObservableCollection<Person> samplePersons = new ObservableCollection<Person>(); samplePersons.Add(new Person() {Name = "张三", Age = 33}); samplePersons.Add(new Person() { Name ="王五", Age= 22 }); samplePersons.Add(new Person() { Name = "李四", Age = 35 }); samplePersons.Add(new Person() { Name = "LearningHard", Age = 27 }); return samplePersons; } }
第二步:实现ViewModel层,实现数据和界面之间的逻辑。在视图模型类中,包含了属性和命令,因为在MVVM中,事件都当成命令来进行处理,其中命令只能与具有Command属性的控件进行绑定。既然要包含命令,首先就需要实现一个命令,这里自定义的命令需要实现ICommand接口。这里我们定义了一个QueryCommand。具体的实现代码如下所示:
public class QueryCommand :ICommand { #region Fields private Action _execute; private Func<bool> _canExecute; #endregion public QueryCommand(Action execute) : this(execute, null) { } public QueryCommand(Action execute, Func<bool> canExecute) { if (execute == null) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } #region ICommand Member public event EventHandler CanExecuteChanged { add { if (_canExecute != null) { CommandManager.RequerySuggested += value; } } remove { if (_canExecute != null) { CommandManager.RequerySuggested -= value; } } } public bool CanExecute(object parameter) { return _canExecute == null ? true : _canExecute(); } public void Execute(object parameter) { _execute(); } #endregion }
接下来就是定义我们的ViewModel类了,具体的实现代码如下所示:
public class PersonListViewModel : INotifyPropertyChanged { #region Fields private string _searchText; private ObservableCollection<Person> _resultList; #endregion #region Properties public ObservableCollection<Person> PersonList { get; private set; } // 查询关键字 public string SearchText { get { return _searchText; } set { _searchText = value; RaisePropertyChanged("SearchText"); } } // 查询结果 public ObservableCollection<Person> ResultList { get { return _resultList; } set { _resultList = value; RaisePropertyChanged("ResultList"); } } public ICommand QueryCommand { get { return new QueryCommand(Searching, CanSearching); } } #endregion #region Construction public PersonListViewModel() { PersonList = PersonDataHelper.GetPersons(); _resultList = PersonList; } #endregion #region Command Handler public void Searching() { ObservableCollection<Person> personList = null; if (string.IsNullOrWhiteSpace(SearchText)) { ResultList = PersonList; } else { personList = new ObservableCollection<Person>(); foreach (Person p in PersonList) { if (p.Name.Contains(SearchText)) { personList.Add(p); } } if (personList != null) { ResultList = personList; } } } public bool CanSearching() { return true; } #endregion #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; #endregion #region Methods private void RaisePropertyChanged(string propertyName) { // take a copy to prevent thread issues PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } #endregion }
第三步:实现View层,设计我们的视图,设置它的DataContext属性为ViewModel类。具体的XAML代码如下所示:
<Window x:Class="MVVMDemo.View.PersonsView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:MVVMDemo.ViewModel" Title="PersonsView" Height="350" Width="400"> <!--设置DataContex是ViewModel类,当然你也可以使用后台代码设置--> <Window.DataContext> <local:PersonListViewModel /> </Window.DataContext> <Grid> <Grid.RowDefinitions> <RowDefinition Height="50"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBox Grid.Row="0" Name="searchtxt" Text="{Binding Path=SearchText, Mode=TwoWay}" HorizontalAlignment="Left" Height="30" Width="280" Margin="10,0,0,0"></TextBox> <Button Grid.Row="0" Name="searchBtn" Content="Search" Command="{Binding Path=QueryCommand}" Width="80" Height="30" HorizontalAlignment="Right" Margin="0,0,10,0"></Button> <DataGrid Grid.Row="1" Name="datGrid" HorizontalAlignment="Center" VerticalAlignment="Top" ItemsSource="{Binding Path=ResultList}" Width="300"></DataGrid> </Grid> </Window>
到此,我们的MVVM的WPF程序就已经完成了,下面就是要看看程序是否达到我们预期的目的。具体的运行结果如下图所示:
四、总结
到这里,本文的内容就分享完了,并且本文也是WPF系列的最后一篇了,希望这个系列可以使得初学者快速上手WPF编程。在接下来的时间里,我打算写一些具有实战性的内容,因为我之前都是分享一些初级的入门系列,接下来打算分享一些实际的项目实现,以及领域驱动设计方面的内容,希望得到大家的督促和支持。
以上是关于WPF中的MVVM模式简单实现的主要内容,如果未能解决你的问题,请参考以下文章