将前面的用户控件与另一个用户控件中的按钮一起使用

Bring the front user control with a button which is inside in another user control

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

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

我想知道如何从一个 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();
        
    }
}

我认为将其留给主窗体而不是在每个 UserControl 中来决定下一步会更容易。这使得移动它们或添加一个新的变得不那么麻烦了。我在这里滥用主窗体作为 Controller/Presenter。

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

用户控件

这是“下一步”按钮的点击事件中的代码:

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

Mainform 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 方法。