我正在使用c#中的windowsFrom。我试图在用户控件中的一个中调用mainfrom方法。 我有这样的主要来自
namespace Project
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
public void TempCommand()
{
StartTemp();
}
}
}
我在用户控件中单击了按钮。当我点击该按钮时,它将打开另一个表单。我在用户控件中有这样的代码。
private TempCalib _tempCalib = new TempCalib();
private void calibBtn_Click(object sender, EventArgs e)
{
_tempCalib.Show();
}
它将打开另一个,我有一个按钮。当我点击此处的“确定”按钮时,我需要调用mainfrom方法。
namespace Project
{
public partial class TempCalib : Form
{
public TempCalib()
{
InitializeComponent();
}
private void OkButton_Click(object sender, EventArgs e)
{
// I need to call the mainfrom "TempCommand" method here.
this.Hide();
}
}
}
任何人都可以帮我解决这个问题。
感谢。
答案 0 :(得分:3)
只需在辅助表单中添加对主表单的引用:
public partial class TempCalib : Form
{
private MainForm _main
public TempCalib(MainForm main) : this()
{
_main = main;
}
/// Other stuffs
}
然后在构建辅助表单时指定值:
private TempCalib _tempCalib;
private void calibBtn_Click(object sender, EventArgs e)
{
if (_tempCalib == null)
_tempCalib = new TempCalib(this);
_tempCalib.Show();
}
如果calibBtn_Click
不在MainForm
内(但它位于UserControl
内),那么您可以将_tempCalib
初始化替换为:
_tempCalib = new TempCalib((MainWindow)FindForm());
然后,您就可以调用主要表单:
private void OkButton_Click(object sender, EventArgs e)
{
_main.TempCommand();
this.Hide();
}
注意:这只是一个选项,您可以创建一个属性来保存MainForm
引用(这样可以重复使用辅助表单,并且它会更加设计友好)而且TempCalib
不是{ {1}}但是UserControl
(非常原始,但对于Form
,您可以只检查其父表单并将其转换为正确的类型。)
这种引用通常是警报。通常,UI组件不应该如此耦合,并且公共UserControl
的方法经常执行某些操作是您Form
中有太多逻辑的信号。如何改善这个?
<强> 1。 DECOUPLE CONTROLS 。那么第一步可能是将它们分离一点,只需在Form
中添加一个事件并使TempCalib
成为其接收者:
MainForm
然后在public partial class TempCalib : Form
{
public event EventHandler SomethingMustBeDone;
private void OkButton_Click(object sender, EventArgs e)
{
OnSomethingMustBeDone(EventArgs.Empty); / TO DO
this.Hide();
}
}
:
MainForm
<强> 2。来自控件的DECOUPLE LOGIC 。 UI经常变化,逻辑不变(当它变化时可能不与UI并行)。这只是第一步(现在private TempCalib _tempCalib;
private void calibBtn_Click(object sender, EventArgs e)
{
if (_tempCalib == null)
{
_tempCalib = new TempCalib();
_tempCalib.SomethingMustBeDone += _tempCalib_SomethingMustBeDone;
// In _tempCalib_SomethingMustBeDone you'll invoke proper member
// and possibly hide _tempCalib (remove it from OkButton_Click)
}
_tempCalib.Show();
}
不知道谁将使用它)。下一步(在表单中发生太多事情时执行)是从表单本身中删除这种逻辑。小例子(非常原始),保持TempCalib
和以前一样(使用事件)并将TempCalib
更改为被动:
MainForm
现在让我们创建一个类来控制流和逻辑:
public partial class MainForm : Form
{
public event EventHandler Calibrate;
protected virtual void OnCalibrate(EventArgs e)
{
// TODO
}
}
是的,您需要编写更多代码,但这会从UI本身解耦逻辑(例如,对某个操作的响应)。当程序增长时,这将帮助您根据需要更改UI,保持逻辑不知道(并在一个明确定义的位置)。我甚至没有提到这将允许您使用不同的资源(人)来编写逻辑和UI(或重用逻辑用于不同的UI,WinForms和WPF,例如)。无论如何,IMO最明显和最好的回报是...... 可读性:你总能知道逻辑在哪里以及UI管理在哪里,没有搜索,没有混乱,没有错误。
第3。从实施中解决逻辑。您还可以执行更多步骤(需要时)。您的控制器仍然知道具体类型(public class MyTaskController
{
private MainForm _main;
private TempCalib _tempCalib;
public void Start()
{
_main = new MainForm();
_main.Calibrate += OnCalibrationRequested;
_main.Show(); // Or whatever else
}
private void OnCalibrationRequested(object sender, EventArgs e)
{
if (_tempCalib == null)
{
_tempCalib = new TempCalib();
_tempCalib.SomethingMustBeDone += OnSomethingMustBeDone();
}
_tempCalib.Show();
}
private OnSomethingMustBeDone(object sender, EventArgs e)
{
// Perform the task here then hide calibration window
_tempCalib.Hide();
}
}
和MainForm
)。如果您需要在运行时选择不同的表单(例如,要有一个复杂的接口和一个简化的接口或使用依赖注入),那么您必须使用接口解耦控制器。举个例子:
TempCalib
答案 1 :(得分:0)
您在usercontrol中创建一个事件,并在mainform中订阅它。 这是通常的方式。
答案 2 :(得分:0)
您可以使用UserControl
中声明的自定义事件。然后您的表单需要处理此事件并调用您要调用的方法。如果您让UserControl
访问您的表单,那么您就会相互硬连接,从而降低UserControl
的可重用性。
例如,在TempCalib
:
public delegate void OkClickedHandler(object sender, EventArgs e);
public event OkClickedHandler OkClicked;
private void OkButton_Click(object sender, EventArgs e)
{
// Make sure someone is listening to event
if (OkClicked == null) return;
OkClicked(sender, e);
this.Hide();
}
你的主体中的:
private void Mainform_Load(object sender, EventArgs e)
{
_tempCalib.OkClicked += CalibOkClicked;
}
private void CalibOkClicked(Object sender, EventArgs e)
{
StartTemp();
}
答案 3 :(得分:0)
Form1代码:
UserControl1 myusercontrol = new UserControl1();
public void TabClose(Object sender,EventArgs e)
{
int i = 0;
i = tabControl1.SelectedIndex;
tabControl1.TabPages.RemoveAt(i);
}
private void Form1_Load(object sender, EventArgs e)
{
myusercontrol.Dock = DockStyle.Fill;
TabPage myTabPage = new TabPage();
myTabPage.Text = "Student";
myTabPage.Controls.Add(myusercontrol);
tabControl1.TabPages.Add(myTabPage);
myusercontrol.OkClick += TabClose;
}
UserControl1代码:
public delegate void OkClickedHandler(Object sender, EventArgs e);
public partial class UserControl1 : UserControl
{
public event OkClickedHandler OkClick;
public UserControl1()
{
InitializeComponent();
}
private void button3_Click(object sender, EventArgs e)
{
if (OkClick == null) return;
OkClick(sender, e);
}
}
答案 4 :(得分:-1)
试试这个:
从用户控制中试试这个:
MainForm form = this.TopLevelControl as MainForm;
form.TempCommand();