You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinForms中子类/孙类向UI传递数据的最优实现方法

WinForms中子类/孙类向UI传递数据的可行方案

针对需要将Loader类中的string result传递到Form UI的场景,以下是几种实用且解耦的实现方案:


方案1:使用IProgress接口(推荐)

WinForms的IProgress<T>接口会自动将回调逻辑切换到UI线程,无需手动处理线程切换,非常适合UI更新场景。

代码修改:

Loader类

public class Loader
{
    private readonly IProgress<string> _logProgress;

    // 构造时注入IProgress实例
    public Loader(IProgress<string> logProgress)
    {
        _logProgress = logProgress;
    }

    public DataTable GetGardensDataTable()
    {
        DataTable dataTable = new DataTable();
        Dictionary<string, object> gardensDetails = new Dictionary<string, object>();

        foreach(DataRow row in dataTable.Rows)
        {
            if (gardensDetails.ContainsKey(row[2].ToString()))
            {
                _log.AddToLog($"Found production duplicate: + {row[2].ToString()}", Color.Red);
                string result = _log.GetLogAsRichText(true);
                
                // 传递日志结果到UI
                _logProgress?.Report(result);
                
                continue;
            }
            // 其他业务逻辑...
        }
        return dataTable;
    }
}

DataGridDataSource类

public class DataGridDataSource
{
    private readonly Loader _loader;
    private readonly ProgressBar _progressBar;

    public DataGridDataSource(ProgressBar progressBar, IProgress<string> logProgress)
    {
        _progressBar = progressBar;
        _loader = new Loader(logProgress);
    }

    public DataTable GetDataSource()
    {
        DataTable gardensTable = _loader.GetGardensDataTable();
        return gardensTable;
    }
}

Form类

private async void Bt_Load_Click(object sender, EventArgs e)
{
    // 创建Progress实例,直接在回调中更新UI(自动切换到UI线程)
    var logProgress = new Progress<string>(result =>
    {
        // 假设用RichTextBox显示日志结果
        richTextBoxLog.Rtf = result;
    });

    DataGridDataSource dataGridDataSource = new DataGridDataSource(_progressBar, logProgress);
    // 用Task.Run避免阻塞UI线程
    dataSource = await Task.Run(() => dataGridDataSource.GetDataSource());
}

方案2:事件委托机制

通过定义事件,让Loader触发事件传递数据,Form订阅事件接收数据,适合需要多个订阅者的场景。

代码修改:

Loader类

public class Loader
{
    // 定义传递日志结果的事件
    public event Action<string> LogResultGenerated;

    public DataTable GetGardensDataTable()
    {
        DataTable dataTable = new DataTable();
        Dictionary<string, object> gardensDetails = new Dictionary<string, object>();

        foreach(DataRow row in dataTable.Rows)
        {
            if (gardensDetails.ContainsKey(row[2].ToString()))
            {
                _log.AddToLog($"Found production duplicate: + {row[2].ToString()}", Color.Red);
                string result = _log.GetLogAsRichText(true);
                
                // 触发事件传递结果
                LogResultGenerated?.Invoke(result);
                
                continue;
            }
            // 其他业务逻辑...
        }
        return dataTable;
    }
}

DataGridDataSource类

public class DataGridDataSource
{
    private readonly Loader _loader;
    private readonly ProgressBar _progressBar;

    public DataGridDataSource(ProgressBar progressBar)
    {
        _progressBar = progressBar;
        _loader = new Loader();
        // 转发Loader的事件到外部
        _loader.LogResultGenerated += (result) => LogResultGenerated?.Invoke(result);
    }

    // 暴露给Form的事件
    public event Action<string> LogResultGenerated;

    public DataTable GetDataSource()
    {
        DataTable gardensTable = _loader.GetGardensDataTable();
        return gardensTable;
    }
}

Form类

private async void Bt_Load_Click(object sender, EventArgs e)
{
    DataGridDataSource dataGridDataSource = new DataGridDataSource(_progressBar);
    // 订阅事件
    dataGridDataSource.LogResultGenerated += UpdateLogUI;
    dataSource = await Task.Run(() => dataGridDataSource.GetDataSource());
}

private void UpdateLogUI(string result)
{
    // 手动判断是否需要切换到UI线程
    if (richTextBoxLog.InvokeRequired)
    {
        richTextBoxLog.Invoke(new Action<string>(UpdateLogUI), result);
        return;
    }
    richTextBoxLog.Rtf = result;
}

方案3:回调函数传递

直接将UI更新方法作为回调传递给Loader,适合简单的一对一数据传递场景。

代码修改:

Loader类

public class Loader
{
    private readonly Action<string> _logCallback;

    // 构造时注入回调方法
    public Loader(Action<string> logCallback)
    {
        _logCallback = logCallback;
    }

    public DataTable GetGardensDataTable()
    {
        DataTable dataTable = new DataTable();
        Dictionary<string, object> gardensDetails = new Dictionary<string, object>();

        foreach(DataRow row in dataTable.Rows)
        {
            if (gardensDetails.ContainsKey(row[2].ToString()))
            {
                _log.AddToLog($"Found production duplicate: + {row[2].ToString()}", Color.Red);
                string result = _log.GetLogAsRichText(true);
                
                // 调用回调传递结果
                _logCallback?.Invoke(result);
                
                continue;
            }
            // 其他业务逻辑...
        }
        return dataTable;
    }
}

DataGridDataSource类

public class DataGridDataSource
{
    private readonly Loader _loader;
    private readonly ProgressBar _progressBar;

    public DataGridDataSource(ProgressBar progressBar, Action<string> logCallback)
    {
        _progressBar = progressBar;
        _loader = new Loader(logCallback);
    }

    public DataTable GetDataSource()
    {
        DataTable gardensTable = _loader.GetGardensDataTable();
        return gardensTable;
    }
}

Form类

private async void Bt_Load_Click(object sender, EventArgs e)
{
    DataGridDataSource dataGridDataSource = new DataGridDataSource(_progressBar, UpdateLogUI);
    dataSource = await Task.Run(() => dataGridDataSource.GetDataSource());
}

private void UpdateLogUI(string result)
{
    if (richTextBoxLog.InvokeRequired)
    {
        richTextBoxLog.Invoke(new Action<string>(UpdateLogUI), result);
        return;
    }
    richTextBoxLog.Rtf = result;
}

内容的提问来源于stack exchange,提问作者Guinea Pig Taco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 22:05:02