WPF中的MVVM實現

1. 概述

MVVM 是WPF中常用的模式: Model - View - ViewModel.

其中 ViewModel 在在View 和 Model中起着雙向連接的作用.

在WPF中 MVVM的運行流程如下:

2.實現

2.1 定義 Model

先定義顯示所需的數據模型 Person:

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

2.2 定義命令 Command

在MVVM中View通過 Command 來通知 ViewModel 進行邏輯操作. 現定義一個查詢的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 定義ViewModel

在 ViewModel 中數據發生變化需要自動顯示在View上, 所以需要實現 INotifyPropertyChanged接口

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 定義界面

界面很簡單, 一個表格顯示所有的信息, 一個輸入框讓用戶輸入查詢條件, 點擊查詢按鈕 進行結果查詢, 結果自動顯示更新到界面.

<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 運行效果

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

3. 項目代碼

此項目代碼在此:

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

歡迎關注我的公衆號獲取最新的文章, 或者 移步我的博客

微信公共號

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