如何从另一个未引用的项目中访问GUI元素?

时间:2017-05-11 10:08:58

标签: c# .net winforms

为简单起见,我有两个项目:

  • 项目A:windows表单应用程序

  • 项目B:C#类库项目

B在A上引用,因此A不能在B上引用。 B得到了整个程序的主要业务,我需要在GUI(项目A)上显示一些信息(反馈,警告,错误......)。

每次将项目B的信息发送回项目A以显示它是非常烦人的。

有什么想法吗?

2 个答案:

答案 0 :(得分:4)

类库应该通知UI项目它可以做出反应的更改并绘制正确的UI。

UI层传递给项目B(回调)的方法有许多方法可以订阅UI层。

下面是一个事件示例。有关提升自定义事件的详细信息,请参阅here

  public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            var projectB = new ProjectB();
            projectB.OnUpdateStatus += projectB_OnUpdateStatus;
            projectB.Run();
        }

        private void projectB_OnUpdateStatus(string message)
        {
            MessageBox.Show(message);
        }
    }



public class ProjectB
{
    public delegate void StatusUpdateHandler(string message);
    public event StatusUpdateHandler OnUpdateStatus;

    public void Run()
    {
        OnUpdateStatus("Updated");
    }
}

你们提到你们已经提到你们在业务中有很多方法,并且需要在业务方法尚未完成处理时在GUI上显示一些信息。

这成为线程的全部。通过上面给出的示例,它可以工作,但UI可能不会更新,因为当前线程太忙于完成工作。在后台任务发生时,UI甚至可能会锁定。

如果你只使用mulitpule线程和上面的aprach,你会发现无法在另一个线程上更新UI的问题。

background worker thread通过在第二个线程上完成工作来解决这个问题,但事件会激活回主UI线程。这使得UI保持活跃和更新。

 public partial class Form1 : Form
    {
        private BackgroundWorker _backgroundfWorker;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _backgroundfWorker = new BackgroundWorker();
            _backgroundfWorker.ProgressChanged += OnUpdateStatus;
            _backgroundfWorker.DoWork += backgroundWorker1_DoWork;
            _backgroundfWorker.WorkerReportsProgress = true;
            _backgroundfWorker.RunWorkerAsync();
        }

        private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            var b = new ProjectB();
            b.OnUpdateStatus += ProjectBOnUpdateStatus;
            b.Run();
        }

        private void ProjectBOnUpdateStatus(string message)
        {
            _backgroundfWorker.ReportProgress(0, message);
        }

        private void OnUpdateStatus(object sender,ProgressChangedEventArgs progressChangedEventArgs)
        {
            MessageBox.Show(progressChangedEventArgs.UserState.ToString());
        }
    }

答案 1 :(得分:1)

类库不应该引用包含用户控件和表单的程序集。它应该是相反的方式。 WinForms中控件和库之间的消息传递通常使用事件或命令。你绝对不应该在类库中拥有像form1.ErrorMessage = "Something bad happened"这样的代码。

  

我在业务中有很多方法,我需要在GUI上显示一些信息,而业务方法还没有完成处理

然后在类库中创建ReportProgress事件或其他内容,并从GUI订阅该事件以显示进度。