myesn

myEsn2E9

hi
github

Windows Forms: 使用 delegate 在业务逻辑中调用 UI 控件

背景#

假设我们有一个 Form,它依赖于单独的业务类,而我们又想在业务类中控制 Form 里面 UI 控件,比如更新进度条之类的,这时候就需要用到 delegate(委托)

delegate 就是包装了方法的引用,将引用作为参数传给其他方法,其它方法拿到引用后,就像调用方法一样去执行它。

这里为了简便,假设我们在业务中需要指定内容的弹窗。

定义委托#

创建一个 Global.cs 文件,在里面将委托和所需的参数定义好:

namespace WindowsFormsApp1
{
    public class Global
    {
        // 定义一个带参数的委托
        public delegate void CallBack(Data data);
    }

    public class Data
    {
        public string Name { get; set; }
    }
}

BLL#

接着将委托作为参数传递给业务方法,在执行委托时:

using System.Threading.Tasks;
using static WindowsFormsApp1.Global;

namespace WindowsFormsApp1
{
    public class BLL
    {
        public void SayHi(CallBack callback) =>
            Task.Run(() => { callback(new Data { Name = "bob" }); });
    }
}

Form#

接着需要在 Form 中初始化委托,并执行业务函数:

using System.Windows.Forms;
using static WindowsFormsApp1.Global;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            // 实例化委托,传入被委托的函数
            var callback = new CallBack(AnyMethod);
            
            // 指定业务逻辑
            new BLL().SayHi(callback);
        }

        private void AnyMethod(Data data) 
            => MessageBox.Show($"Hi, {data.Name}");        
    }
}

就好了。

优化#

C# 提供了两个封装好了的委托:

  • Action:带参数没有返回值
  • Func:带参数带返回值

这样我们就不用自己去定义委托,所以我们改一下程序。

Global#

删除 Global 类。

BLL#

public void SayHi(Action<Data> callback)

Form#

new BLL().SayHi(new Action<Data>(AnyMethod));
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。