当前位置: 首页 > article >正文

记录 | WPF基础学习MVVM例子讲解1

目录

  • 前言
  • 一、NotificationObject与数据属性
    • 创建个类,声明NotificationObject
  • 二、DelegateCommand与命令属性
  • 三、View与ViewModel的交互(难点)
    • 在ViewModel文件下创建MainWindowViewModel
    • 数据和方法绑定
    • 资源指定
  • 代码下载
  • 四、优势体现
  • 代码下载
  • 更新时间


前言

参考文章:
参考视频:《深入浅出WPF》系列高清视频教程 | 讲师:刘铁猛

自己的感想


在这里插入图片描述

一、NotificationObject与数据属性

创建个类,声明NotificationObject

用于双向的数据绑定

在这里插入图片描述

internal class NotificationObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChange(string propertyName)
    {
        if(this.PropertyChanged != null)
        {
            this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

PropertyChanged 事件:订阅者(如 UI 控件)通过监听此事件感知属性变化。

RaisePropertyChange 方法:手动触发事件,传递发生变更的属性名。

上面的RaisePropertyChange()方法可以优化:

public void RaisePropertyChange(string propertyName)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

二、DelegateCommand与命令属性

做操作传输的命令属性命名为DelegateCommand
CanExecute决定命令是否可用
Execute执行命令的实际逻辑
CanExecuteChanged在命令的可执行状态变化时通知UI更新。

在这里插入图片描述

    internal class DelegateCommand : ICommand
    {
        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            if (this.CanExecuteFunc == null)
            {
                return true;
            }
            return this.CanExecuteFunc(parameter); 
        }

        public void Execute(object parameter)
        {
            if (this.ExecuteAction == null)
            {
                return;
            }
            this.ExecuteAction(parameter);
        }

        public Action<object> ExecuteAction { get;set; }
        public Func<object,bool> CanExecuteFunc { get; set; }
    }

三、View与ViewModel的交互(难点)

NotificaitonObject.cs是ViewModel文件夹中类的基类。里面的其他类都要继承NotificationObject.cs类。

在ViewModel文件下创建MainWindowViewModel

   internal 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"); }
       }
       
       //1个方法

       public DelegateCommand AddCommand {  get; set; }

       private void Add(Object parameter)
       {
           this.Result = this.Input1 + this.Input2;
       }

       public MainWindowViewModel()
       {
           this.AddCommand = new DelegateCommand();
           this.AddCommand.ExecuteAction = new Action<object>(this.Add);
       }

   }

数据和方法绑定

在这里插入图片描述

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Button x:Name="btnSave" Content="Save"/>
        <Grid Grid.Row="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <TextBox x:Name="slider1" Grid.Row="0" FontSize="24" Margin="4" 
                     Background="LightBlue"
                     Text="{Binding Input1}"/>
            <TextBox x:Name="slider2" Grid.Row="1" FontSize="24" Margin="4"
                     Background="LightBlue"
                     Text="{Binding Input2}"/>
            <TextBox x:Name="slider3" Grid.Row="2" FontSize="24" Margin="4"
                     Background="LightBlue"
                     Text="{Binding Result}"/>
            <Button Name="addBtn" Grid.Row="3" Content="Add" Width="120" Height="80" Command="{Binding AddCommand}" />
        </Grid>
    </Grid>

资源指定

在这里插入图片描述

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainWindowViewModel();
        }

代码下载

代码下载

四、优势体现

这种框架的优势体现在:逻辑功能不变的情况下,前端怎么改都可以很快实现功能,只要映射回原来的方法和属性即可。
下面就是直接将前端UI代码拷贝进来,后端不变,效果依旧是result = input1+input2.
在这里插入图片描述
在这里插入图片描述

代码下载

代码下载


更新时间

  • 2025-02-11:创建。
  • 2025-02-12:完善案例。

http://www.kler.cn/a/545355.html

相关文章:

  • DeepSeek 突然来袭,AI 大模型变革的危机与转机藏在哪?
  • 【Elasticsearch】simple_query_string
  • BGP配置华为——路由汇总
  • 天地图(uniapp)搜索、定位自己、获取标记点的经纬度
  • 2025年金三银四经典自动化测试面试题
  • Redis 数据类型 Set 集合
  • 嵌入式EasyRTC实时通话支持海思hi3516cv610,编译器arm-v01c02-linux-musleabi-gcc
  • .NET 9.0 的 Blazor Web App 项目,自定义日志 TLog V2 使用备忘
  • 为什么配置Redis时候要序列化配置呢
  • 无人机飞行试验大纲
  • joint_info.npz 找不到
  • AI代码生成器:前端开发的新纪元
  • 2024BaseCTF_week4_web上
  • 稀土紫外屏蔽剂:科技护航,守护您的健康与美丽
  • 【C语言】C语言 实践课题选题系统(源码+报告+数据文件)【独一无二】
  • 本地部署 Ollama 模型并实现本地可视化聊天界面(使用 DeepSeek)
  • win10中mstsc远程Centos-Stream 9图形化界面
  • 李超线段树 树链剖分 学习笔记
  • Linux进阶——nfs服务器
  • 常见的缓存更新策略