winform 中特别是子窗体向父窗体传递参数的时候,通常使用事件回调机制。
1.简单的事件回调:
1.1定义一个EventHub类
public static class EventBus
{
// 定义事件
public static event Action<string> MessagePublished;
// 发布消息的方法
public static void PublishMessage(string message)
{
MessagePublished?.Invoke(message);
}
}
1.2 在需要使用的窗体类中写一个方法并调用
private void OnMessageReceived(string message)
{
// 确保UI更新在主线程执行
if (this.InvokeRequired)
{
this.Invoke(new Action<string>(OnMessageReceived), message);
return;
}
//执行具体逻辑
}
public MainForm()
{
InitializeComponent();
// 订阅事件
EventBus.MessagePublished += OnMessageReceived;
}
2.通用事件回调机制
2.1 定义一个EventBus类
public static class EventBus
{
private static readonly Dictionary<Type, List<Delegate>> _eventHandlers = new Dictionary<Type, List<Delegate>>();
// 发布事件
public static void Publish<TEventArgs>(TEventArgs e) where TEventArgs : EventArgs
{
Type eventType = typeof(TEventArgs);
if (_eventHandlers.ContainsKey(eventType))
{
foreach (Delegate handler in _eventHandlers[eventType].ToArray())
{
((Action<TEventArgs>)handler)(e);
}
}
}
// 订阅事件
public static void Subscribe<TEventArgs>(Action<TEventArgs> handler) where TEventArgs : EventArgs
{
Type eventType = typeof(TEventArgs);
if (!_eventHandlers.ContainsKey(eventType))
{
_eventHandlers[eventType] = new List<Delegate>();
}
_eventHandlers[eventType].Add(handler);
}
// 取消订阅
public static void Unsubscribe<TEventArgs>(Action<TEventArgs> handler) where TEventArgs : EventArgs
{
Type eventType = typeof(TEventArgs);
if (_eventHandlers.ContainsKey(eventType))
{
_eventHandlers[eventType].Remove(handler);
if (_eventHandlers[eventType].Count == 0)
{
_eventHandlers.Remove(eventType);
}
}
}
}
// 通用事件参数基类
public class EventArgs<T> : EventArgs
{
public EventArgs(T value)
{
Value = value;
}
public T Value { get; private set; }
}
// 特定类型的事件参数
public class StringEventArgs : EventArgs<string>
{
public StringEventArgs(string value) : base(value)
{
}
}
public class IntEventArgs : EventArgs<int>
{
public IntEventArgs(int value) : base(value)
{
}
}
// 自定义事件参数示例
public class UserLoginEventArgs : EventArgs
{
public string Username { get; set; }
public DateTime LoginTime { get; set; }
public UserLoginEventArgs(string username)
{
Username = username;
LoginTime = DateTime.Now;
}
}
2.2是需要的窗体中使用,如主窗体
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
// 订阅事件
EventBus.Subscribe<StringEventArgs>(OnStringEvent);
EventBus.Subscribe<UserLoginEventArgs>(OnUserLogin);
}
private void OnStringEvent(StringEventArgs e)
{
// 确保在UI线程上更新控件
if (InvokeRequired)
{
Invoke(new Action<StringEventArgs>(OnStringEvent), e);
return;
}
lblStatus.Text = $"收到字符串事件: {e.Value}";
}
private void OnUserLogin(UserLoginEventArgs e)
{
if (InvokeRequired)
{
Invoke(new Action<UserLoginEventArgs>(OnUserLogin), e);
return;
}
lblUserStatus.Text = $"用户 {e.Username} 于 {e.LoginTime} 登录";
}
private void btnPublishEvent_Click(object sender, EventArgs e)
{
var num = new Random().Next(0, 100);
// 发布事件
EventBus.Publish(new StringEventArgs(num.ToString()));
EventBus.Publish(new UserLoginEventArgs("詹三"));
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
// 取消订阅事件(重要:避免内存泄漏)
EventBus.Unsubscribe<StringEventArgs>(OnStringEvent);
EventBus.Unsubscribe<UserLoginEventArgs>(OnUserLogin);
}
}

805

被折叠的 条评论
为什么被折叠?



