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

3

众所周知,有一些类似于这种解决方案的解决方案,但我无法用它们来解决我的问题。 我有两个用户控件:

  • 第一个用户控件生成一个报表对象。
  • 第二个用户控件显示它。

我有一个主窗体将两个控件连接起来。

这两个控件是在 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”以显示它?

enter image description here


2
最好的方法可能是在controlUserReport中创建一个公共属性,其中包含报告对象,并在controlDocViewer中创建另一个以获取它。 - Pikoh
你能修改用户控件的代码吗? - Mong Zhu
是的,我可以 @MongZhu - dbz
3个回答

6
您应该使用事件来实现此功能。在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);
    }
}

UserControlB类如何知道userControlA实例的存在? - Sasha Bond

0
另一种方法是使用BehaviorSubject(需要System.Reactive)。一旦数据添加到BehaviorSubject中,所有订阅的地方都可以看到信息。一个非常基本的例子:
  1. 创建一个类来表示您的数据。例如: DataService.cs
public static BehaviorSubject<YourDataType> MyAwesomeData { get; } = new BehaviorSubject<YourDataType> (null);

在您的 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...
        }

      });


0

上面的帖子很好,除了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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接