20240216 WPF 实现数据修改后,主动通知界面更改以及MVVMLight 的使用

1)按钮和下面的文本框分别关联的对应的函数和一个属性;

2)关联对应的实例化的一个数据;

3)这个类中需要指定INotifyPropertyChanged接口,然后实现该接口对应的事件声明public event PropertyChangedEventHandler PropertyChanged;

4)Name参数,需要使用完全方式声明,在set中,增加对事件的调用,相当于,每次修改值的时候就出发事件,然后界面会收到该事件;发送事件中,一个参数中包括了事件的Name,形成对应;

5)界面收到后,会根据该参数进行更新。

            <Button Name="bt1" Content="点击我" Command="{Binding myCommand}"  Margin="5" Height="30"/>
            <TextBox Name="tx1" Text="{Binding Name}"  Margin="5" Height="30"/>


指定对应的数据源
            this.bt1.DataContext = new MainViewModel();
            this.tx1.DataContext = this.bt1.DataContext;

声明的类
    public class MainViewModel:INotifyPropertyChanged
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { 
                name = value;
                PropertyChanged?.Invoke(this,new PropertyChangedEventArgs("Name"));
            }
        }

        public ClassMyCommand myCommand { get; set; }
        public MainViewModel() {
            myCommand = new ClassMyCommand(Show);
            Name = "first";
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void Show()
        {
            Name = "点击了我。";
            MessageBox.Show(Name);
        }
    }

6)在上面基础上修改简化,

首先声明一个基类,依然使用原来的通知接口,里面实现一个方法,用于实现参数修改后,调用事件

    public class NotifyPropertyChangedBaseClass : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName]string propertyname = "")//通过该方法可以直接获取调用者的名称 前提是需要有默认参数
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
        }
    }



    public class MainViewModel: NotifyPropertyChangedBaseClass  //INotifyPropertyChanged 修改原来基于接口,现在基于基类
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { 
                name = value;
                //PropertyChanged?.Invoke(this,new PropertyChangedEventArgs("Name"));
                //OnPropertyChanged("Name");//参数可以不写,
                OnPropertyChanged();//参数可以不写,

            }
        }

        public ClassMyCommand myCommand { get; set; }
        public MainViewModel() {
            myCommand = new ClassMyCommand(Show);
            Name = "first";
        }

        //public event PropertyChangedEventHandler PropertyChanged;//删除掉这个

        public void Show()
        {
            Name = "点击了我。";
            MessageBox.Show(Name);
        }
    }

7)使用MVVMLight

通过NuGet安装该安装包后,上面自己写的命令绑定和通知都可以删除;直接使用社区包中已经封装好的函数

    public class MainViewModel: ViewModelBase //现在基于基类
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { 
                name = value;
                RaisePropertyChanged();//调用事件

            }
        }
        public RelayCommand myCommand { get; set; }//定义命令
        public MainViewModel() {
            myCommand = new RelayCommand(Show);
            Name = "first";
        }
        public void Show()
        {
            Name = "点击了我。";
            MessageBox.Show(Name);
        }
    }

其中是三个点

基类——ViewModelBase //现在基于基类

事件调用——RaisePropertyChanged();//调用事件

命令定义——public RelayCommand myCommand { get; set; }//定义命令

命令赋值——myCommand = new RelayCommand(Show);

其中命令 有两个重载,一个带参数,一个努努带参数,带参数的调用函数的时候需要传递带参数的函数。根据需要调用。

GalaSoft.MvvmLight.CommandWpf.RelayCommand

GalaSoft.MvvmLight.CommandWpf.RelayCommand<T>

如果是传递参数

        public RelayCommand<string> myCommand{ get; set; }//定义命令
        public MainViewModel() {
            myCommand = new RelayCommand<string> (Show);
            Name = "first";
        }
        public void Show(string txt )
        {
            Name = "点击了我。";
            MessageBox.Show(txt);
        }


XAML中需要将参数传递进来
        Command="{Binding myCommand}" 
        CommandParameter="{Binding ElementName=tx2, Path=Text}"

8)MVVMLight中的 消息注册和发送

      //启动的时候定义一个消息接收器,当接收到消息,且关键字是 myToken1,这可以自定义,后就会自己执行委托 Show  
      Messenger.Default.Register<string>(this,"myToken1",Show);

          Messenger.Default.Send( txt, "myToken1");//传递需要参数和 标识,用于和注册的匹配

9)使用Microsoft.Toolkit.Mvvm 包或者CommunityToolkit.Mvvm 两个是一样使用的,建议使用后面的。

消息注册换了一个名字

            //启动的时候定义一个消息接收器,当接收到消息,且关键字是 myToken1,这可以自定义,后就会自己执行委托 Show  

            //Messenger.Default.Register<string>(this, "myToken1", Show);
            WeakReferenceMessenger.Default.Register<string, string>(this, "myToken1", (o, e) => {
                Show(e);
            });
  public class MainViewModel: ObservableObject //ViewModelBase  MVVMLight //现在基于基类Microsoft.Toolkit.Mvvm.ComponentModel.ObservableObject
  {
      private string name;
      public string Name
      {
          get { return name; }
          set { 
              name = value;
              //RaisePropertyChanged();//调用事件
              OnPropertyChanged();//调用事件

          }
      }
      public RelayCommand<string> myCommand{ get; set; }//定义命令
      public MainViewModel() {
          myCommand = new RelayCommand<string> (Show);
          Name = "first";
      }
      public void Show(string txt )
      {
          Name = "点击了我。";
          //MessageBox.Show(txt);
          WeakReferenceMessenger.Default.Send( txt, "myToken1");//传递需要参数和 标识,用于和注册的匹配
      }
  }

其他都没有变。

基类——ObservableObject//现在基于基类

事件调用——OnPropertyChanged();//调用事件

命令定义——public RelayCommand myCommand { get; set; }//定义命令

命令定义——public RelayCommand<string> myCommand{ get; set; }//定义命令 带参数的

命令赋值——myCommand = new RelayCommand<string> (Show);

通过命令牌发送消息 触发事件——

//Messenger.Default.Send( txt, "myToken1");//传递需要参数和 标识,用于和注册的匹配 MVVMLight
WeakReferenceMessenger.Default.Send( txt, "myToken1");//传递需要参数和 标识,用于和注册的匹配

注册事件——

            //启动的时候定义一个消息接收器,当接收到消息,且关键字是 myToken1,这可以自定义,后就会自己执行委托 Show  

            //Messenger.Default.Register<string>(this, "myToken1", Show);
            WeakReferenceMessenger.Default.Register<string, string>(this, "myToken1", (o, e) => {
                Show(e);})

说明  o 的类型是 this  <string, string> 第一个string 对应的是e,第二个对应的是 "myToken1" 如果传递的不是string就要在注册的时候也修改

好的,这里我可以给你一个WPF使用MvvmLight实现MVVM的工程实例。 首先,你需要在Visual Studio中安装MvvmLight框架。可以通过NuGet来安装MvvmLight库,具体步骤如下: 1. 在Visual Studio中打开你的WPF工程。 2. 在Solution Explorer窗口中右键单击工程,选择“Manage NuGet Packages”。 3. 在“NuGet Package Manager”窗口中,在搜索框中输入“MvvmLight”,选择“MvvmLight”并安装。 接下来,我们就可以开始实现MVVM模式了。 1. 创建一个新的ViewModel类,继承自ViewModelBase类。 ```csharp using GalaSoft.MvvmLight; public class MainViewModel : ViewModelBase { //ViewModel的属性和命令 } ``` 2. 在ViewModel中实现需要绑定的属性和命令。 ```csharp private string _message; public string Message { get { return _message; } set { if (_message != value) { _message = value; RaisePropertyChanged(() => Message); } } } private RelayCommand _showMessageCommand; public RelayCommand ShowMessageCommand { get { if (_showMessageCommand == null) { _showMessageCommand = new RelayCommand(() => { MessageBox.Show(Message); }); } return _showMessageCommand; } } ``` 3. 在View中绑定ViewModel的属性和命令。 ```xaml <Window x:Class="WpfApp1.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:WpfApp1" xmlns:vm="clr-namespace:WpfApp1.ViewModel" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.DataContext> <vm:MainViewModel /> </Window.DataContext> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <TextBox Text="{Binding Message, UpdateSourceTrigger=PropertyChanged}" /> <Button Grid.Row="1" Content="Show Message" Command="{Binding ShowMessageCommand}" /> </Grid> </Window> ``` 在这个例子中,我们创建了一个MainViewModel类,其中包含了一个Message属性和一个ShowMessageCommand命令。在View中,我们使用DataContext将ViewModel实例与View绑定,并使用Binding将ViewModel的属性和命令绑定到View上。 这样,我们就成功地使用MvvmLight实现MVVM模式。当用户在TextBox中输入文字并点击Button时,将会弹出一个对话框显示用户输入的文字。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值