首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在用户控件单击事件中以主机形式切换用户控件

在用户控件单击事件中以主机形式切换用户控件
EN

Stack Overflow用户
提问于 2019-03-07 22:04:10
回答 2查看 249关注 0票数 4

这听起来可能很愚蠢,但我很难弄明白这一点;如果能提供任何帮助,我们将不胜感激:

我有两个名为“Safety_Check”和“OEE_Track”的用户控件。在我的MainForm中,我有一个名为MainForm的面板,这是我显示两个用户控件的地方。我的主表单上有两个按钮,我在两者之间动态切换,没有任何问题。

Safety_Check用户控件;

代码语言:javascript
复制
public partial class Safety_Check : UserControl
    {
        private static Safety_Check _instance;

        public static Safety_Check instance
        {
            get
            {
                if (_instance == null)
                    _instance = new Safety_Check();
                return _instance;
            }
        }

        public Safety_Check()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ///////------------------------
        }

    }

OEE_Track用户控制

代码语言:javascript
复制
public partial class OEE_Track : UserControl
    {

        private static OEE_Track _instance;

        public static OEE_Track instance
        {
            get
            {
                if (_instance == null)
                    _instance = new OEE_Track();
                return _instance;
            }
        }

        public OEE_Track()
        {
            InitializeComponent();
        }
    }

MainForm:

代码语言:javascript
复制
public partial class MainForm : Form
    {
     private void btn_reg_Click(object sender, EventArgs e)
        {
            if (!pnl_main_controller.Contains(Safety_Check.instance))
            {
                pnl_main_controller.Controls.Add(Safety_Check.instance);
                Safety_Check.instance.Dock = DockStyle.Fill;
                Safety_Check.instance.BringToFront();
            }
            else
            {
                Safety_Check.instance.BringToFront();
            }        }

       private void btn_OEE_Click(object sender, EventArgs e)
        {
            if (!pnl_main_controller.Contains(OEE_Track.instance))
            {
                pnl_main_controller.Controls.Add(OEE_Track.instance);
                OEE_Track.instance.Dock = DockStyle.Fill;
                OEE_Track.instance.BringToFront();
            }
            else
            {
                OEE_Track.instance.BringToFront();
            }
     }

我想做的是,在我的“Safety_Check”用户控件上有一个名为“Button1”的按钮,每当我按下这个按钮时,我希望“Safety_Check”在“pnl_main_controller”上消失,并将“OEE_Track”带到面板上。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-12 19:53:58

对于控件之间的交互,有几种解决方案。控件是类,与任何其他类一样,它们可以使用它们的公共属性和方法或使用某种中介来相互交互。

在这种情况下,您的控件不需要相互了解,也不需要直接交互:

  • 他们可以要求另一个知道这两个控件的对象为他们做这件事。
  • 或者,他们可以提出他们的请求通知,而订阅该通知的人将送达该通知。

要让另一个对象为它们执行任务,您有多个解决方案。例如,您可以在父窗体和子控件中实现特定接口,将父接口强制转换到该特定接口,并调用为您完成工作的特定方法。

要引发请求通知,一个简单的解决方案是依赖事件。您可以在子控件中创建事件,并在需要父控件为您做一些事情时引发它。然后在父程序中订阅该事件并执行任务。

示例-使用事件

我假设您的UserControl1中包含了Button1,并且您已经处理了Button1Click事件。然后您可以创建Button1Clicked事件并在Button1单击时引发它:

代码语言:javascript
复制
public event EventHandler Button1Clicked;
private void Button1_Click(object sender, EventArgs e)
{
    Button1Clicked?.Invoke(this, e);
}

然后,在父表单中,订阅事件并做您想做的任何事情:

代码语言:javascript
复制
private void userControl11_Button1Clicked(object sender, EventArgs e)
{
    //Hide userControl11 and show userControl21 
}

示例-使用接口

我想,您有一个有几个标准方法的接口:

代码语言:javascript
复制
public interface IDoSomething
{
    void DoSomething();
    void DoSomethingElse();
}

您已经在父表单中实现了该接口:

代码语言:javascript
复制
public class Form1: Form, IDoSomething
{
    // ...

    public void DoSomething()
    {
        //Hide userControl11 and show userControl21 
    }
    public void DoSomethingElse()
    {
        // ...
    }
}

然后在您的用户控件中:

代码语言:javascript
复制
private void Button1_Click(object sender, EventArgs e)
{
    var f = FindForm() as IDoSomething;
    if(f!=null)
        f.DoSomething();
}
票数 4
EN

Stack Overflow用户

发布于 2019-03-18 16:46:37

我想详述一下Reza Aghaei的回答。我认为它可能会比现在更好。

第一种方法

如果我是您,我将有一些接口ICheckedView,它至少有一个方法来实现,如下所示:

代码语言:javascript
复制
ICheckedView
{
    void Continue();
}

现在,我们可以将此接口应用于解决方案中的任何类,但最有可能是视图。接下来,我将使您的主表单实现这个接口并实现所需的方法。在本例中,我们希望主窗体从面板中移除控件,并添加一个新控件。坦率地说,我们的安全检查控件不需要(也可能不应该)知道其他控件或接下来会发生什么。它只是用来控制的。

最终,您需要向Safety_Check的构造函数中添加一个公共属性,或者,甚至可能是一个参数,其中包含一个ICheckedView。当您的安全检查控件被单击时,它可以告诉被传递到它的人(我们会说客户端),它必须继续。

第二种方法

这可以用行动代表来完成。

如果将Action委托添加到安全检查中,则只需插入签名与该委托(void methodName())匹配的任何方法即可。您的Safety_Check控件的构造函数应该包括一个操作,该操作将被分配给类的一个私有字段。然后,当需要调用时,可以直接调用该操作。

关于这种方法的注记

因为我们可能一开始就从UI线程调用,所以我们可能没有问题,但是您需要考虑线程的安全性。调用所需的模式可以帮助您解决这一问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55053527

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档