WPF MVVM实例三

在没给大家讲解wpf mwm示例之前先给大家简单说下MVVM理论知识:

WPF技术的主要特点是数据驱动UI,所以在使用WPF技术开发的过程中是以数据为核心的,WPF提供了数据绑定机制,当数据发生变化时,WPF会自动发出通知去更新UI。

  我们使用模式,一般是想达到高内聚低耦合。在WPF开发中,经典的编程模式是MVVM,是为WPF量身定做的模式,该模式充分利用了WPF的数据绑定机制,最大限度地降低了Xmal文件和CS文件的耦合度,也就是UI显示和逻辑代码的耦合度,如需要更换界面时,逻辑代码修改很少,甚至不用修改。与WinForm开发相比,我们一般在后置代码中会使用控件的名字来操作控件的属性来更新UI,而在WPF中通常是通过数据绑定来更新UI;在响应用户操作上,WinForm是通过控件的事件来处理,而WPF可以使用命令绑定的方式来处理,耦合度将降低。

首先MVVM设计模式的结构

 

 

Views: 由Window/Page/UserControl等构成,通过DataBinding与ViewModels建立关联;
ViewModels:由一组命令,可以绑定的属性,操作逻辑构成;因为View与ViewModel进行了解耦,我们可以对ViewModel进行Unit Test;

Models:可以是实体对象或者Web服务;
下面通过一个简单的例子,来介绍一些WPF MVVM模式。首先项目结构:

 

DelegateCommand.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WpfApp13.Commands;
 
namespace WpfApp13.ViewModels
{
    class MainWindowViewModel:NotificationObject
    {
        private double  input1;
 
        public double Input1
        {
            get { return input1; }
            set
            {
                input1 = value;
                this.RaisePropertyChange("Input1");
            }
        }
 
        private double input2;
 
        public double Input2
        {
            get { return input2; }
            set
            {
                input2 = value;
                this.RaisePropertyChange("Input2");
            }
        }
 
        private double result;
 
        public double Result
        {
            get { return result; }
            set
            {
                result = value;
                this.RaisePropertyChange("Result");
            }
        }
 
        public DelegateCommand AddCommand { get; set; }
 
        public void Add(object parameter)
        {
            this.Result = this.Input1 + this.Input2;
        }
 
        public MainWindowViewModel()
        {
            this.AddCommand = new DelegateCommand();
            this.AddCommand.ExcuteAction = new Action<object>(this.Add);
        }
    }
}

  MainWindowViewModel.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WpfApp13.Commands;
 
namespace WpfApp13.ViewModels
{
    class MainWindowViewModel:NotificationObject
    {
        private double  input1;
 
        public double Input1
        {
            get { return input1; }
            set
            {
                input1 = value;
                this.RaisePropertyChange("Input1");
            }
        }
 
        private double input2;
 
        public double Input2
        {
            get { return input2; }
            set
            {
                input2 = value;
                this.RaisePropertyChange("Input2");
            }
        }
 
        private double result;
 
        public double Result
        {
            get { return result; }
            set
            {
                result = value;
                this.RaisePropertyChange("Result");
            }
        }
 
        public DelegateCommand AddCommand { get; set; }
 
        public void Add(object parameter)
        {
            this.Result = this.Input1 + this.Input2;
        }
 
        public MainWindowViewModel()
        {
            this.AddCommand = new DelegateCommand();
            this.AddCommand.ExcuteAction = new Action<object>(this.Add);
        }
    }
}

  NotificationObject.CS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace WpfApp13.ViewModels
{
    class NotificationObject : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
 
        public void RaisePropertyChange(string propertyName)
        {
            if(this.PropertyChanged!=null)
            {
                this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

  MainWindow.xaml.CS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WpfApp13.ViewModels;
 
namespace WpfApp13
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainWindowViewModel();
        }
 
        
 
    }
 
    
 
}
 
MainWindow.xaml

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<Window x:Class="WpfApp13.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp13"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel>
            <Slider Name="slider1" MinHeight="25" Value="{Binding Input1}"/>
            <Slider Name="slider2" MinHeight="25" Value="{Binding Input2}"/>
            <Slider Name="slider3" MinHeight="25" Value="{Binding Result}"/>
            <Button Name="addButton" Content="ADD" FontSize="30" MinHeight="40" Command="{Binding AddCommand}"/>
        </StackPanel>    
    </Grid>
</Window>

  

运行效果:

分别拖动滑块slider1和slider2,点击按钮后slider3就会自动变化

 

百度网盘源码下载地址:

链接:https://pan.baidu.com/s/1AvBncokY8SiW0fd9XqrPRw 

提取码:ttpo 

 

posted @   zls366  阅读(154)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示