在用户控件之间传递数据 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 后,所有订阅的地方都可以看到信息。一个非常基本的例子:
- 创建一个 class 来表示您的数据。前任:
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);
}
- 最后,您的解决方案中使用 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...
}
});
已知有一些与此类似的解决方案,但我无法用它们解决我的问题。 我有两个用户控件:
- 第一个生成报表对象。
- 第二个显示它。
我有一个链接两个控件的主窗体。
这两个控件是在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 后,所有订阅的地方都可以看到信息。一个非常基本的例子:
- 创建一个 class 来表示您的数据。前任: 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);
}
- 最后,您的解决方案中使用 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...
}
});