WinForm 使用 ReactiveUI 实现数据绑定(MVVM) 与跨页面数据同步(MessageBus)

参考

环境

软件/系统 版本 说明
Windows windows 10 专业版 22H2 64 位操作系统, 基于 x64 的处理器
Microsoft Visual Studio Community 2022 (64 位) - Current 版本 17.14.4
.NET Framework 4.8
ReactiveUI.Winforms 20.4.0.0 nuget依赖库

预览

实现内容:

  1. 页面与数据分离,实现数据的双向绑定
  2. 跨页面的数据同步
    image

正文

主要代码

  1. Form1ViewModel.cs
    using ReactiveUI;
    
    namespace WindowsFormsReactiveUI1.ViewModel
    {
    	public class Form1ViewModel : ReactiveObject
    	{
    		private int _id;
    		private string _name;
    		private int _age;
    		private string _twoWayMessage;
    
    		public int Id
    		{
    			get => _id;
    			set => this.RaiseAndSetIfChanged(ref _id, value);
    		}
    
    		public string Name
    		{
    			get => _name;
    			set => this.RaiseAndSetIfChanged(ref _name, value);
    		}
    
    		public int Age
    		{
    			get => _age;
    			set => this.RaiseAndSetIfChanged(ref _age, value);
    		}
    
    		public string TwoWayMessage
    		{
    			get => _twoWayMessage;
    			set => this.RaiseAndSetIfChanged(ref _twoWayMessage, value);
    		}
    	}
    }
    
    
  2. Form1.cs
    using ReactiveUI;
    using System;
    using System.Diagnostics;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using WindowsFormsReactiveUI1.ViewModel;
    
    namespace WindowsFormsReactiveUI1
    {
    	public partial class Form1 : Form, IViewFor<Form1ViewModel>
    	{
    		object IViewFor.ViewModel
    		{
    			get => ViewModel;
    			set => ViewModel = (Form1ViewModel)value;
    		}
    
    		public Form1ViewModel ViewModel { get; set; }
    
    		public Form1()
    		{
    			InitializeComponent();
    			this.WhenActivated(d =>
    			{
    				d(this.Bind(ViewModel, vm => vm.Id, v => v.textBox1.Text));
    				d(this.Bind(ViewModel, vm => vm.Name, v => v.textBox2.Text));
    				d(this.Bind(ViewModel, vm => vm.Age, v => v.textBox3.Text));
    				d(this.OneWayBind(ViewModel, vm => vm.Id, v => v.textBox4.Text));
    				d(this.OneWayBind(ViewModel, vm => vm.Name, v => v.textBox5.Text));
    				d(this.OneWayBind(ViewModel, vm => vm.Age, v => v.textBox6.Text));
    				d(this.OneWayBind(ViewModel, vm => vm.TwoWayMessage, v => v.textBox7.Text));
    			});
    			ViewModel = new Form1ViewModel();
    			// 测试数据同步
    			Task.Run(() => {
    				int i = 0;
    				while (true) {
    					Thread.Sleep(1000);
    					this.Invoke(new Action(() =>
    					{
    						ViewModel.Age = ++i;
    					}));
    				}
    			});
    			// 订阅消息-实现名字更新
    			MessageBus.Current.Listen<string>("UpdateMessage").Subscribe(message =>
    			{
    				Debug.WriteLine($"收到标签为Form2的消息更新:{message}");
    				this.Invoke(new Action(() =>
    				{
    					ViewModel.TwoWayMessage = message;
    				}));
    			});
    		}
    
    		private void button2_Click(object sender, EventArgs e)
    		{
    			// 清空
    			ViewModel.TwoWayMessage = "";
    			// 打开新窗口
    			Form2 form2 = new Form2();
    			form2.Show();
    		}
    	}
    }
    
    
  3. Form2.cs
    using ReactiveUI;
    using System;
    using System.Windows.Forms;
    
    namespace WindowsFormsReactiveUI1
    {
    	public partial class Form2 : Form
    	{
    		public Form2()
    		{
    			InitializeComponent();
    		}
    
    		private void textBox1_TextChanged(object sender, EventArgs e)
    		{
    			TextBox t1 = sender as TextBox;
    			MessageBus.Current.SendMessage(t1.Text, "UpdateMessage");
    		}
    	}
    }
    
    
posted @ 2025-07-06 21:25  夏秋初  阅读(97)  评论(0)    收藏  举报