MVVM——Model-View-ViewModel的缩写形式。

    Model——可以理解为带有字段、属性的类。 View——可以理解为我们看到的UI。 View Model——在ViewModel之间,起到连接作用,并且使得ViewModel层分离。View Model不仅仅是Model的包装,它还包含了程序逻辑,以及 Model扩展。例如,如果Model中有一个公开属性不需要在UI上显示,此时我们不需要在View Model中去定义它。 在MVVM中,VM的地位举足轻重。使用MVVM模式具有以下几个特点: ①视图的cs文件包含极少数的代码,其核心逻辑都被放在<font style="color:#E8323C;">View Model</font>类中,从而使得程序逻辑与视图耦合度降低。 <font style="color:#E8323C;">View Model</font>类作为<font style="color:#E8323C;">View</font><font style="color:#E8323C;">DataContext</font> ③在MVVM下,所有的事件和动作都被当成命令,如按钮的点击操作,此时不是触发点击事件,而是绑定到一个点击命令,再由命令去执行对应的逻辑

    第三点很关键,因为在MVVM中,事件都被当成命令来进行处理,其中命令只能与具有Command属性的控件进行绑定

    1. namespace WpfApplication1
    2. {
    3. //第一步:自然是数据部分了,即Model层的实现。在这里定义了一个Person类,其中包含了2个基本的属性。
    4. public class PersonModel
    5. {
    6. public string Name { get; set; }
    7. public int Age { get; set; }
    8. }
    9. }
    1. namespace WpfApplication1
    2. {
    3. //为了进行测试,下面创建一个静态方法来获得测试数据。
    4. public class PersonDataHelper
    5. {
    6. public static ObservableCollection<PersonModel> GetPersons()
    7. {
    8. ObservableCollection<PersonModel> samplePersons = new ObservableCollection<PersonModel>();
    9. samplePersons.Add(new PersonModel() { Name = "张三", Age = 33 });
    10. samplePersons.Add(new PersonModel() { Name = "王五", Age = 22 });
    11. samplePersons.Add(new PersonModel() { Name = "李四", Age = 35 });
    12. samplePersons.Add(new PersonModel() { Name = "LearningHard", Age = 27 });
    13. return samplePersons;
    14. }
    15. }
    16. }
    1. namespace WpfApplication1
    2. {
    3. //第二步:实现ViewModel层,实现数据和界面之间的逻辑。在视图模型类中,包含了属性和命令,
    4. //因为在MVVM中,事件都当成命令来进行处理,其中命令只能与具有Command属性的控件进行绑定。
    5. //既然要包含命令,首先就需要实现一个命令,这里自定义的命令需要实现ICommand接口。
    6. //这里我们定义了一个QueryCommand。具体的实现代码如下所示:
    7. public class QueryCommand : ICommand
    8. {
    9. #region Fields
    10. private Action _execute;
    11. private Func<bool> _canExecute;
    12. #endregion
    13. public QueryCommand(Action execute) : this(execute, null)
    14. {
    15. }
    16. public QueryCommand(Action execute, Func<bool> canExecute)
    17. {
    18. if (execute == null)
    19. throw new ArgumentNullException("execute");
    20. _execute = execute;
    21. _canExecute = canExecute;
    22. }
    23. #region ICommand Member
    24. public event EventHandler CanExecuteChanged
    25. {
    26. add
    27. {
    28. if (_canExecute != null)
    29. {
    30. CommandManager.RequerySuggested += value;
    31. }
    32. }
    33. remove
    34. {
    35. if (_canExecute != null)
    36. {
    37. CommandManager.RequerySuggested -= value;
    38. }
    39. }
    40. }
    41. public bool CanExecute(object parameter)
    42. {
    43. return _canExecute == null ? true : _canExecute();
    44. }
    45. public void Execute(object parameter)
    46. {
    47. _execute();
    48. }
    49. #endregion
    50. }
    51. }
    1. namespace WpfApplication1
    2. {
    3. public class PersonListViewModel : INotifyPropertyChanged
    4. {
    5. #region Fields
    6. private string _searchText;
    7. private ObservableCollection<PersonModel> _resultList;
    8. #endregion
    9. #region Properties
    10. public ObservableCollection<PersonModel> PersonList { get; private set; }
    11. // 查询关键字
    12. public string SearchText
    13. {
    14. get { return _searchText; }
    15. set
    16. {
    17. _searchText = value;
    18. RaisePropertyChanged("SearchText");
    19. }
    20. }
    21. // 查询结果
    22. public ObservableCollection<PersonModel> ResultList
    23. {
    24. get { return _resultList; }
    25. set
    26. {
    27. _resultList = value;
    28. RaisePropertyChanged("ResultList");
    29. }
    30. }
    31. public ICommand QueryCommand
    32. {
    33. get { return new QueryCommand(Searching, CanSearching); }
    34. }
    35. #endregion
    36. #region Construction
    37. public PersonListViewModel()
    38. {
    39. PersonList = PersonDataHelper.GetPersons();
    40. _resultList = PersonList;
    41. }
    42. #endregion
    43. #region Command Handler
    44. public void Searching()
    45. {
    46. ObservableCollection<PersonModel> personList = null;
    47. if (string.IsNullOrWhiteSpace(SearchText))
    48. {
    49. ResultList = PersonList;
    50. }
    51. else
    52. {
    53. personList = new ObservableCollection<PersonModel>();
    54. foreach (PersonModel p in PersonList)
    55. {
    56. if (p.Name.Contains(SearchText))
    57. {
    58. personList.Add(p);
    59. }
    60. }
    61. if (personList != null)
    62. {
    63. ResultList = personList;
    64. }
    65. }
    66. }
    67. public bool CanSearching()
    68. {
    69. return true;
    70. }
    71. #endregion
    72. #region INotifyPropertyChanged Members
    73. public event PropertyChangedEventHandler PropertyChanged;
    74. #endregion
    75. #region Methods
    76. private void RaisePropertyChanged(string propertyName)
    77. {
    78. // take a copy to prevent thread issues
    79. PropertyChangedEventHandler handler = PropertyChanged;
    80. if (handler != null)
    81. {
    82. handler(this, new PropertyChangedEventArgs(propertyName));
    83. }
    84. }
    85. #endregion
    86. }
    87. }
    1. <Window x:Class="WpfApplication1.PersonsView"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:local="clr-namespace:WpfApplication1"
    5. Title="PersonsView" Height="300" Width="300">
    6. <Window.DataContext>
    7. <local:PersonListViewModel />
    8. </Window.DataContext>
    9. <Grid>
    10. <Grid.RowDefinitions>
    11. <RowDefinition Height="50"/>
    12. <RowDefinition Height="*"/>
    13. </Grid.RowDefinitions>
    14. <TextBox Grid.Row="0" Name="searchtxt" Text="{Binding Path=SearchText, Mode=TwoWay}"
    15. HorizontalAlignment="Left" Height="30" Width="280" Margin="10,0,0,0">
    16. </TextBox>
    17. <Button Grid.Row="0" Name="searchBtn" Content="Search" Command="{Binding Path=QueryCommand}"
    18. Width="80" Height="30" HorizontalAlignment="Right" Margin="0,0,10,0">
    19. </Button>
    20. <DataGrid Grid.Row="1" Name="datGrid"
    21. HorizontalAlignment="Center"
    22. VerticalAlignment="Top" ItemsSource="{Binding Path=ResultList}" Width="300">
    23. </DataGrid>
    24. </Grid>
    25. </Window>