0

我有一个程序,它有一个父表单,然后创建一个子表单。单击子表单中的 updateButton 后,我希望触发父表单中的 searchButton。

但是,出于保护原因,我收到错误消息。我已经尝试将所有内容设置为 Public 只是为了查看,但对我仍然不起作用。

错误 1 ​​'SalesSystem.SystemForm.searchButton' 由于其保护级别 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();
        }
    }
}
4

5 回答 5

2

您的searchButton按钮控件private在 WinForm 中默认设置为。您已经说过您将所有内容都设置为公开,但我认为您的意思是您已将所有内容都设置在已发布的代码中。有几种方法可以解决这个问题。直接的解决方法是简单地转到 Visual Studio 设计器,选择按钮,并将其Modifier属性设置为internalor 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);

如果您没有关闭表单,那么您可以创建您自己的事件处理程序,您的父表单订阅该事件处理程序。

于 2013-05-18T12:17:25.603 回答
1

您有 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();
    }
}
于 2013-05-18T12:24:58.900 回答
0

我累了,可能会遗漏一些东西,但这是正确的行为。

您的子表单不直接从您的父表单继承。

您的父表单具有受保护的级别,因此只有它和扩展它的类才能访问该方法。

2个解决方案:

  1. 将您的子表单更改为:

公共部分类 UpdateForm : SystemForm

  1. 将方法更改为公开

public void searchButton_Click(对象发送者,EventArgs e)

于 2013-05-18T12:31:40.737 回答
0

您应该使用“模型视图控制器”“模型视图演示者”模式来处理这种事情。

每个表单应该只关心向用户显示其内容。在响应 UI 事件(例如按钮单击)时,每个表单(即每个"View")都应该简单地引发一个事件,通知控制器/演示者发生了某些事情。

然后控制器/演示者应该做出适当的响应。然后将不同表单(例如您的示例中的父表单和子表单)连接在一起的逻辑封装在 Controller 类中。这种逻辑实际上并不属于任何一种形式。

前段时间,我写了一个示例,演示了一个简单的设计来在另一个答案中执行此类操作。我不会在这里全部复制/粘贴,而是给你一个链接:

选中 form2 上的复选框时如何使 Form1 label.text 更改?

你必须向下滚动才能看到我的答案。它与您正在做的事情大体相似;希望它对你有意义!按照说明制作测试应用程序并运行它以查看会发生什么。

于 2013-05-18T12:15:34.897 回答
0

您可以从 UpdateForm 中公开一个搜索事件并在 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();
        }
    }
}
于 2013-05-18T12:38:31.583 回答