我有一个程序,它有一个父表单,然后创建一个子表单。单击子表单中的
updateButton
后,我希望父表单中的 searchButton
触发。
但是出于保护原因,我得到了一个错误。我已经尝试将所有内容设置为 Public 只是为了看看,仍然对我不起作用。
Error 1 'SalesSystem.SystemForm.searchButton' is unaccessible due to 它的保护级别 SalesSystem\UpdateForm.cs 111 20 SalesSystem
这就是我目前所拥有的。
家长代码
namespace SalesSystem
{
public partial class SystemForm : Form
{
public SystemForm()
{
InitializeComponent();
}
protected void searchButton_Click(object sender, EventArgs e)
{
//search code
}
private void updateButton_Click(object sender, EventArgs e)
{
try
{
UpdateForm upForm = new UpdateForm(resultBox.SelectedItems[0].Text, dbdirec, dbfname);
upForm.ShowDialog(this);
}
catch (Exception)
{
//
}
}
}
儿童密码
namespace SalesSystem
{
public partial class UpdateForm : Form
{
public UpdateForm(string selectedPerson, string dbdirec, string dbfname)
{
InitializeComponent();
}
private void updateButton_Click(object sender, EventArgs e)
{
//do stuff
SystemForm parent = (SystemForm)this.Owner;
parent.searchButton.PerformClick();
this.Close();
}
}
}
您的
searchButton
按钮控件在 WinForm 中默认设置为 private
。您已经说过您将所有内容都设置为公开,但我假设您的意思是您已经在已发布的代码中设置了所有内容。有几种方法可以解决这个问题。直接的解决方法是简单地转到 Visual Studio 设计器,选择按钮,然后将其 Modifier
属性设置为 internal
或 public
.
但是,您似乎要在之后立即关闭表格,所以我只让我的父表格订阅表格的
FormClosing
事件。
UpdateForm upForm = new UpdateForm(resultBox.SelectedItems[0].Text, dbdirec, dbfname);
upForm.FormClosing += (s, o) =>
{
//your code for what the parent class should do
};
upForm.ShowDialog(this);
如果您不关闭表单,那么您可以创建自己的父表单订阅的事件处理程序。
你有2个选择:
在您的父表单中创建一个
public void search()
方法。然后,您无需访问父窗体上的按钮并调用其点击事件,而是直接运行搜索代码。新方法没有绑定到 GUI 元素,从不同的形式访问它是没有问题的。更好的解决方案是创建一个委托。委托是将在运行时分配的执行目标。父窗体仍然有一个
public void search()
方法。当它创建子窗体时,它会将该函数的名称作为参数传递。子窗体不知道父窗体(与第一个选项相反,子窗体必须知道有一个名为 search()
的方法)。当需要通知创建子表单的人时,将调用委托。这是一个小例子:
public partial class SystemForm : Form
{
public delegate void dSearch();
public SystemForm()
{
InitializeComponent();
}
protected void searchButton_Click(object sender, EventArgs e)
{
search();
}
private void search()
{
//search code
}
private void updateButton_Click(object sender, EventArgs e)
{
try
{
UpdateForm upForm = new UpdateForm(resultBox.SelectedItems[0].Text, dbdirec, dbfname, search);
upForm.ShowDialog(this);
}
catch (Exception)
{
//
}
}
}
和孩子形式:
public partial class UpdateForm : Form
{
private SystemForm.dSearch _target;
public UpdateForm(string selectedPerson, string dbdirec, string dbfname, SystemForm.dSearch target)
{
_target = target;
InitializeComponent();
}
private void updateButton_Click(object sender, EventArgs e)
{
//do stuff
_target();
this.Close();
}
}
您应该使用“模型视图控制器”或“模型视图展示器”模式来处理这种事情。
每个表单应该只关心向用户显示其内容。当涉及到响应按钮点击等 UI 事件时,每个表单(即每个
"View"
)应该简单地引发一个事件,通知控制器/演示者发生了一些事情。
控制者/演示者然后应该做出适当的回应。然后将不同表单(例如您的示例中的父表单和子表单)连接在一起的逻辑封装在 Controller 类中。这种逻辑实际上不属于任何一种形式。
前段时间我在另一个答案中写了一个例子来演示一个简单的设计来做这种事情。与其将其全部复制/粘贴到此处,不如给您一个链接:
如何在选中 form2 上的复选框时更改 Form1 label.text?
你必须向下滚动才能看到我的答案。它与您正在做的大致相似;希望它对你有意义!按照说明制作测试应用程序并运行它,看看会发生什么。
我累了,可能会遗漏一些东西,但这是正确的行为。
您的子表单不直接继承自您的父表单。
您的父表单具有受保护级别,因此只有它和扩展它的类才能访问该方法。
2 解决方案:
公共部分类 UpdateForm : SystemForm
public void searchButton_Click(object sender, EventArgs e)
您可以从 UpdateForm 中公开一个 Search Event 并在 SystemForm 中订阅该事件
namespace SalesSystem
{
public partial class SystemForm : Form
{
public SystemForm()
{
InitializeComponent();
}
protected void searchButton_Click(object sender, EventArgs e)
{
//search code
}
private void updateButton_Click(object sender, EventArgs e)
{
try
{
UpdateForm upForm = new UpdateForm(resultBox.SelectedItems[0].Text, dbdirec, dbfname);
upForm.OnSearch += Search;
upForm.ShowDialog(this);
}
catch (Exception)
{
//
}
}
private void Search(string searchParameter)
{
....
}
}
namespace SalesSystem
{
public delegate void SearchEventHandler(string searchParameter);
public partial class UpdateForm : Form
{
public event SearchEventHandler OnSearch;
public UpdateForm(string selectedPerson, string dbdirec, string dbfname)
{
InitializeComponent();
}
private void updateButton_Click(object sender, EventArgs e)
{
//do stuff
OnSearch("SearchThis");
this.Close();
}
}
}