从子窗体按钮访问父窗体按钮

时间:2013-05-18 12:03:57

标签: c# winforms parent-child protection

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

但是出于保护原因我收到错误。我试过将所有东西设置为公开只是为了看,仍然不适合我。

  

错误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();
        }
    }
}

5 个答案:

答案 0 :(得分:2)

默认情况下,您的searchButton按钮控件在WinForm中设置为private。您已经说过要将所有内容都设置为公开,但我认为您的意思是您已将所有内容都设置为公开发布的代码。有几种方法可以解决这个问题。直接修复只需转到Visual Studio设计器,选择按钮,并将其Modifier属性设置为internalpublic

但是,您似乎正在关闭您的表单,所以我只是让我的父表单订阅表单的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);

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

答案 1 :(得分:1)

您有两个选择:

  • 在父表单中创建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();
    }
}

答案 2 :(得分:0)

您应该使用"Model View Controller""Model View Presenter"模式来处理此类问题。

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

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

我写了一个例子,演示了一个简单的设计,在不久前的另一个答案中做这种事情。而不是在这里复制/粘贴它,我只是给你一个链接:

How to make Form1 label.text change when checkbox on form2 is checked?

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

答案 3 :(得分:0)

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

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

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

2个解决方案:

  1. 将您的子表单更改为:
  2. public partial class UpdateForm:SystemForm

    1. 将方法更改为公开
    2. public void searchButton_Click(object sender,EventArgs e)

答案 4 :(得分: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();
        }
    }
}