在用户控件之间传递数据 C#

Passing data between usercontrols c#

已知有一些与此类似的解决方案,但我无法用它们解决我的问题。 我有两个用户控件:

我有一个链接两个控件的主窗体。

这两个控件是在DLL中创建的,添加到 主要形式如下:

//ADDS THE FIRST CONTROL TO THE PANEL CONTROL
  myDll.controlUserReport userControlA = new myDll.controlUserReport();
  panelControl1.Controls.Add(userControlA);
  userControlA.Dock = DockStyle.Left;

//ADDS THE SECOND CONTROL TO THE PANEL CONTROL
   myDll.controlDocViewer userControlB = new myDll.controlDocViewer();
   panelControl1.Controls.Add(userControlB);
   userControlB.Dock = DockStyle.Fill;

当我点击一个按钮时,如何将在第一个控件 controlUserReport 中创建的 Report 对象传递给另一个用户控件 controlDocViewer 以显示它?

您应该为此使用事件。在UserControlA声明事件:

//Declare EventHandler outside of class
public delegate void MyEventHandler(object source, Report r);

public class UserControlA
{
    public event MyEventHandler OnShowReport;

    private void btnShowReport_Click(object sender, Report r)
    {
         OnShowReport?.Invoke(this, this.Report);
    }
}

UserControlB订阅事件并展示报告:

public class UserControlB
{
    // Do it in Form_Load or so ...
    private void init()
    {
       userControlA.OnShowReport += userControlA_OnShowReport;
    }

    private void userControlA_OnShowReport(object sender, Report r)
    {
        // Show the report
        this.ShowReport(r);
    }
}

上面的 post 很好,除了 init() 方法不应在 ControlB 中,而应在父窗体中,如下所示:

public class frmMain : Form
{
    private void frmMain_Load(object sender, EventArgs e)        
    {
       // subscribe/glue
       userControlA.OnShowReport += userControlB.OnShowReport;
       userControlB.OnShowReport += userControlA.OnShowReport;
    }



public class UserControlA
{
    public event EventHandlerNodeCopy OnDataCopy;
    public TreeNode NodeCopied { get; set; }

    private void some_method(string z, TreeNode trn)
    {
        OnDataCopy?.Invoke(this, trn);
        ...
    }

    public void frmJsTree_OnDataCopy(object source, TreeNode tn)
    {
        NodeCopied = tn;
    }


public class UserControlB
{
    public event EventHandlerNodeCopy OnDataCopy;
    public TreeNode NodeCopied { get; set; }

    private void another_method(int i, TreeNode trn)
    {
        OnDataCopy?.Invoke(this, trn);
        ...
    }

    public void frmJsTree_OnDataCopy(object source, TreeNode tn)
    {
        NodeCopied = tn;
    }


    enter code here

另一种方法是使用 BehaviorSubject(需要 System.Reactive)。在 BehaviorSubject 中添加 data 后,所有订阅的地方都可以看到信息。一个非常基本的例子:

  1. 创建一个 class 来表示您的数据。前任: DataService.cs
public static BehaviorSubject<YourDataType> MyAwesomeData { get; } = new BehaviorSubject<YourDataType> (null);
  1. 在您 UserControlA 中(可能在按钮的 clickEvent 中)或其他:
private void btnShowReport_Click(object sender, MouseButtonEventArgs e)
{
  // Do some stuffs to prepare the data...
  YourDataType myDataReportPrepared = null; // something;

  // Here you update your DataInfo on BehaviorSubject
  DataService.MyAwesomeData.OnNext(myDataReportPrepared);
}
  1. 最后,您的解决方案中使用 subscribe 的每个地方都将收听该数据,例如在您的 UserControlB 中:

// This will trigger every time MyAwesomeData.OnNext() is executed.
DataService.MyAwesomeData.Subscribe(item =>
      {
        if (item != null){
           // Do something with it...Like populate some Datagrid...
        }

      });