首页 > 解决方案 > 使用位于另一个用户控件内部的按钮带来前端用户控件

问题描述

我有一个表单和至少 6 个用户控件(每个 UC 都有一个按钮可以转到下一个 UC)

  1. 我想先把UC1带到前面
  2. UC1有一个弹出按钮UC2
  3. ETC...

我想知道如何从一个 UC 转到另一个的架构。

表格代码:

    public partial class TestProgram : Form
{
    public TestProgram()
    {
        InitializeComponent();

        UC21.BringToFront();
    }

    private void TestProgram_Load(object sender, EventArgs e)
    {
        UC21.Hide();
        UC31.Hide();
        UC41.Hide();
        UC51.Hide();
        UC61.Hide();
        UC71.Hide();
        UC81.Hide();
    }
}

UC1 代码:

public partial class UC1 : UserControl
{
    public UC2 UC2{ get; set; } 
    
    public UC1()
    {
        InitializeComponent();

    }

    private void NextPageBut_Click(object sender, EventArgs e)
    {
        UC2.BringToFront();
        
    }
}

标签: c#.netvisual-studiowinformsuser-controls

解决方案


我认为如果你把它留给你的主窗体来决定下一步是什么而不是在每个用户控件中会更容易。这使得移动它们或添加一个新的变得不那么麻烦。我在这里滥用主窗体作为控制器/演示者。

UserControls 被添加到表单的 Controls 集合中。如果我们不使用 BringToFront 而只是简单地隐藏和显示,我们可以让主窗体找到当前显示的用户控件(因为它的 Visible 属性设置为 true),然后隐藏那个并显示下一个用户控件。UserControl 具有 Parent 属性,我们可以将其转换为主窗体,以便我们可以在其公共接口上调用方法。

用户控制

这是 Next 按钮的 click 事件中的代码:

public partial class UC1 : UserControl
{
     public UC1()
    {
        InitializeComponent();
    }

    private void NextPageBut_Click(object sender, EventArgs e)
    {
        // get and cast to the parent form
        var tpf = (TestProgram) this.Parent;
        // tell the mainform we want to go Next
        tpf.Next();
    }
}

主窗体 Next 方法

此方法在控件上循环,同时保持状态以决定要采取的操作。

// our various states
enum NextState {
    Start = 0,
    ShowOne,
    Done,
}

public void Next() 
{
    NextState state = NextState.Start;
    // loop over controls
    // if you want to 
    foreach(var ctl in Controls)
    {
        // find the UserControl ones
        if (ctl is UserControl) 
        {
            var uc = (UserControl) ctl;
            // based on our state ...
            switch(state)
            {
                case NextState.Start:
                    // hide and do the next state
                    if (uc.Visible) 
                    {
                        uc.Hide();
                        state = NextState.ShowOne;
                    }
                break;
                case NextState.ShowOne:
                    // show and do the next state
                    uc.Show();
                    state = NextState.Done;
                break;
                default:
                    // do nothing
                break;
            }
        }
    }
    if (state != NextState.Done) {
        // nothing got set
        // show the first one? 
        // something else?
    }
}

如果您真的想使用 BringToFront,那么您必须更加小心,并且可能执行 SendToBack 以维护 Controls 集合中的顺序。或者将第二个集合与您的用户控件一起使用,并相应地调整 Next 方法。


推荐阅读