MVVM implementation in WPF

1 Overview

MVVM is a commonly used pattern in WPF: Model - View - ViewModel.

Among them, ViewModel plays the role of two-way connection between View and Model.

The operation process of MVVM in WPF is as follows:

2. Realize

2.1 Define Model

First define the data model Person required for display:

namespace WPFDemo.DataBinding {
    public class Person{
 
        public string Name { get; set; }
 
        public int Age { set; get; }
    }
}

2.2 Define command Command

In MVVM, View notifies ViewModel to perform logical operations through Command. Now define a query Command:

namespace WPFDemo.DataBinding {
    public class QueryCommand : ICommand {
 
        private Action executeAction;
        private Func<bool> canExecuteFun;
 
        public QueryCommand(Action executeAction) : this(executeAction, null) {
 
        }
 
        public QueryCommand(Action executeAction, Func<bool> canExecuteFun) {
            this.executeAction = executeAction ?? throw new ArgumentNullException(nameof(executeAction));
            this.canExecuteFun = canExecuteFun;
        }
 
        public void Execute(object parameter) {
            executeAction();
        }
 
        public bool CanExecute(object parameter) {
            return canExecuteFun == null ? true : canExecuteFun();
        }
 
        public event EventHandler CanExecuteChanged {
            add {
                if (canExecuteFun != null) {
                    CommandManager.RequerySuggested += value;
                }
            }
            remove {
                if (canExecuteFun != null) {
                    CommandManager.RequerySuggested -= value;
                }
            }
        }
    }
}

2.3 Define ViewModel

Data changes in the ViewModel need to be automatically displayed on the View, so INotifyPropertyChangedthe interface needs to be implemented

namespace WPFDemo.DataBinding {
    public class DataBindingViewModule : INotifyPropertyChanged {
        //保存用户输入的数据
        private string searchText;
 
        public string SearchText {
            get => searchText;
            set {
                searchText = value;
                RaisePropertyChanged(nameof(SearchText));
            }
        }
        //查询的结果
        private ObservableCollection<Person> resultList;
 
        public ObservableCollection<Person> ResultList {
            get => resultList;
            private set {
                resultList = value;
                RaisePropertyChanged(nameof(ResultList));
            }
        }
 
        // 基础数据
        public ObservableCollection<Person> Persons { get; private set; }
 
        //查询命令 绑定到按钮
        public ICommand QueryCommand {
            get => new QueryCommand(Searching, CanSearch);
        }
 
        public DataBindingViewModule() {
            Persons = new ObservableCollection<Person> {
                new Person() {Name = "zhangsan", Age = 11},
                new Person() {Name = "lisi", Age = 10},
                new Person() {Name = "wangwu", Age = 11}
            };
            ResultList = Persons;
        }
 
        // 搜索逻辑
        private void Searching() {
            if (string.IsNullOrEmpty(SearchText)) {
                ResultList = Persons;
            } else {
                ObservableCollection<Person> collection = new ObservableCollection<Person>();
                foreach (var person in Persons) {
                    if (person.Name.Contains(SearchText)) {
                        collection.Add(person);
                    }
                }
 
                if (collection.Count != 0) {
                    ResultList = collection;
                }
            }
        }
 
        //是否可搜索
        private bool CanSearch() {
            return true;
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        [NotifyPropertyChangedInvocator]
        protected virtual void RaisePropertyChanged(string propertyName) {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

2.4 Define the interface

The interface is very simple, a table displays all the information, an input box allows the user to enter query conditions, click the query button to query the results, and the results are automatically displayed and updated to the interface.

<Page x:Class="WPFDemo.DataBinding.DataBindingPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:local="clr-namespace:WPFDemo.DataBinding"
      mc:Ignorable="d"
      d:DesignHeight="450" d:DesignWidth="800"
      Title="DataBindingPage">
 
    <Page.DataContext>
        <local:DataBindingViewModule/>
    </Page.DataContext>
 
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
 
        <TextBox
            x:Name="SearchTb" Text="{Binding Path=SearchText, Mode=TwoWay}"
            HorizontalAlignment="Center" VerticalAlignment="Center"
            Grid.Row="0" Grid.Column="0" Width="320"/>
        <Button
            x:Name="QueryBtn" Command="{Binding QueryCommand}"
            Height="32" Width="48" Content="Query" Grid.Row="0" Grid.Column="1"
            HorizontalAlignment="Center" VerticalAlignment="Center"/>
 
        <DataGrid
            x:Name="ResultDg" ItemsSource="{Binding Path=ResultList}"
            Grid.Row="1" Grid.ColumnSpan="2" Grid.Column="0" Width="400" IsReadOnly="True"
            VerticalAlignment="Top" HorizontalAlignment="Center">
        </DataGrid>
    </Grid>
</Page>

2.5 Operation effect

The transfer of the external link image failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly.

3. Item code

The project code is here:

WPFDemo/DataBinding at master · Dev-Wiki/WPFDemo](https://github.com/Dev-Wiki/WPFDemo/tree/master/DataBinding)

Welcome to pay attention to my official account to get the latest articles, or move to my blog

WeChat public account

Guess you like

Origin blog.csdn.net/DevWiki/article/details/104641241