winforms 多个窗体之间的转换(WinForm/C#)[已关闭]

ckocjqey  于 2023-01-31  发布在  C#
关注(0)|答案(1)|浏览(209)

已关闭。此问题需要details or clarity。当前不接受答案。
**想要改进此问题?**添加详细信息并通过editing this post阐明问题。

3天前关闭。
Improve this question
我想在表单之间进行转换。表单不止两个。我需要一些允许在几个表单之间转换的东西,如果我正在通过两个或更多表单,当我单击主菜单时,所有打开的旧页面都将关闭。我正在使用WinForms和C#
我只是使用.Show().ShowDialog()方法将其作为弹出窗口打开,但在第二个选项中,它仍然像浏览历史一样,逐页返回

oogrdqng

oogrdqng1#

实现此目的的方法之一是创建一个公共基类Form(在本例中我们称之为BaseActivity),并使用Application.OpenForms集合为继承它的表单创建一个特别管理器。在重复可见性循环中使用Show()时,一个棘手的问题是,如果调用Close()方法,它将破坏窗口句柄。由于这个原因,BaseActivity将把canceler方法附加到FormClosing事件,并在应用程序关闭时将其删除。

流式布局的最小示例

  • 新窗体将在可见窗体的右侧打开。
  • 单击[HomeIcon]关闭 * 所有 * 子窗口,只打开主窗口。
  • 单击[X]关闭单个窗口,并将剩余的可见表单向左滑动(动画)

这样,当您单击主菜单时,所有打开的旧页面都会关闭

public class BaseActivity : Form
{
    public static HomeActivity? MainWnd { get; protected set; }
    
    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        if (!DesignMode)
        {
            FormClosing -= OnActivityClosing; // In case handle is recreated
            FormClosing += OnActivityClosing;
        }
    } 
    protected void OnActivityClosing(object? sender, FormClosingEventArgs e) { 
        e.Cancel = true; // Prevent destruction of handle if `Close` is called.
        Hide();
    }

Application.OpenForms创建的实用工具集合

internal static BaseActivity[] VisibleForms => 
        Application
        .OpenForms
        .Cast<BaseActivity>()
        .Where(_ => _.Visible)
        .ToArray();
    internal static BaseActivity[] VisibleChildForms => 
        VisibleForms
        .Where(_ => !_.GetType().Name.Equals(nameof(HomeActivity)))
        .ToArray();

“当我单击主菜单时,所有打开的旧页面都将关闭。”

internal void OnClickHome(object? sender, EventArgs e){
        foreach (var form in VisibleChildForms) form.Hide();
    }

任何窗体都可以打开其他窗口。

protected virtual void MenuItemClicked(string activity)
    {
        if (activity == "Exit")
        {
            // Remove the handler. Allow close.
            foreach (var open in Application.OpenForms.OfType<BaseActivity>())
            {
                open.FormClosing -= open.OnActivityClosing;
            }
            Application.Exit();
        }
        else
        {
            var name = $"{activity}Activity";
            BaseActivity? form = 
                VisibleChildForms.FirstOrDefault(_ => _.GetType().Name.Equals(name));
            if (form == null)
            {   // Create if NOT EXIST
                switch (activity)
                {
                    case "Flights": form = new FlightsActivity(); break;
                    case "Cars": form = new CarsActivity(); break;
                    case "Cart": form = new CartActivity(); break;
                    default:
                        throw new NotImplementedException($"{activity}");
                }
            }
            if (!form.Visible)
            {  // Show if NOT VISIBLE
                var x = MainWnd.Location.X;
                foreach (var open in VisibleForms)
                {
                    x += 10;
                    x += open.Width;
                }
                form.StartPosition = FormStartPosition.Manual;
                form.Location = new Point(x, MainWnd.Location.Y);
                form.Show();
            }
        }
    }
}

用[X]关闭单个窗口后,滑动窗口位置(动画)以填充差距。

internal void OnClickX(object? sender, EventArgs e)
    {
        Close();
        var x = MainWnd.Location.X;
        foreach (var open in VisibleChildForms)
        {
            x += 10;
            x += open.Width;
            int animate = open.Location.X;
            while(animate > x)
            {
                open.Location = new Point(animate, MainWnd.Location.Y);
                animate--;
            }
            open.Location = new Point(x, MainWnd.Location.Y);
        }
    }
}

相关问题