C#在同一表单中的接口之间切换

时间:2015-09-24 19:55:16

标签: c# forms visual-studio panel

我用Java编写了一个数据库程序,我现在希望将它转换为C#用于学习目的。

我遇到的一个问题是在同一个用户界面中切换不同的视图。我想在整个程序中保留一个表单,并在用户浏览程序时更改其上显示的内容。

我试图在我添加包含按钮的用户控件的表单上添加一个面板。单击该按钮时,应丢弃初始用户控件并显示新的用户控件。

到目前为止,这是我的代码;

public partial class Form1 : Form
{

    UserControl1 myControl1 = new UserControl1();
    UserControl2 myControl2 = new UserControl2();

    public Form1()
    {
        InitializeComponent();
        panel1.Controls.Add(myControl1);
    }

    public void PanelVersion2()
    {
        panel1.Controls.Remove(myControl1);
        panel1.Controls.Add(myControl2);
    }
}

在我的UserControl类中;

public partial class UserControl1 : UserControl
{
        public event EventHandler AddControl;
        public UserControl1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form1 fm = new Form1();
            fm.PanelVersion2();
        }
    }
}

这种意识形态是创建用户界面的“最佳”方式吗?是否有更有效的方式在保持原始形式的同时通过用户界面移动?

3 个答案:

答案 0 :(得分:2)

您不要让表单显示表单,而不是让表单决定显示哪个面板,因为从代码中正确跟踪应用程序中的窗口是非常困难的。是的,您可以遍历Application.OpenFormssomeContainer.Controls来查找您正在寻找的内容,但您并不想要它。

您需要应用design patterns,例如MVP,MVVM,MVC或application controller

在这个答案中解释这些模式会使它有点长(我可能会稍后尝试),但尝试搜索上述条款。

答案 1 :(得分:0)

也许您应该将表单的职责与用户控件的职责分开,并且可能将主表单引用到控件中可能会有所帮助

UserControl1 myControl1 = new UserControl1 { MainForm = this };

这只是一个学习示例的建议,也许您应该搜索UI设计模式,以便做更详细的事情。

答案 2 :(得分:0)

由于问题是关于WinForms而我不想,嗯..违反惯例并回答建议您立即使用不同的技术我会先回答这个问题然后提供什么事情。我建议你实际做。无论有谁说,永远不要使用MDI。它不适用于此,只会让您的用户感到困惑。所以这就是一个基于小视图的控制器框架,采用简约的方法。

首先是主机表单的接口(IHost.cs):

public interface IHost
{
    /// <summary>
    ///     Destroys the current view and creates a new from name
    /// </summary>
    /// <param name="name">The name of the view you wish to start</param>
    void SwitchView(string name);

    View CurrentView { get; }
}

然后,视图界面。现在,visual studio会告诉你这是设计中的UserControl。错误不是!它是,但不应该用作一个。如果你删除它在右侧创建的类,那么实际上不要把东西放在那个设计器上。这是所有视图的基础,如果您编辑此视图,则所有视图都将具有该部分界面。 (View.cs)

    using System.Windows.Forms; //Above your namespace

    public class View : UserControl
    {
        /// <summary>
        ///     Warning! Attempting to use this constructor and host (eg switching views)
        ///     will result in exceptions unless host is manually set
        /// </summary>
        protected View()
        {
        }
        protected View(IHost host) 
        {
            Host = host;
        }

        public virtual IHost Host { get; }
    }

现在主机表单看起来像这样(HostForm.cs,这是我的入口点和我向主要用户展示的东西):

    using System.Collections.Generic; //Above your namespace
    using System.Windows.Forms; //Above your namespace

    public partial class HostForm : Form, IHost
    {
        public View CurrentView { get; private set; }

        public HostForm()
        {
            InitializeComponent();
            SwitchView("UserLabel");
        }

        public void SwitchView(string name)
        {
            Controls.Remove(CurrentView);
            CurrentView = CreateViewFromName(name);
            Controls.Add(CurrentView);
            CurrentView.Show();
        }

        private View CreateViewFromName(string name)
        {
            switch (name.ToLowerInvariant())
            {
                case "userlabel":
                    return new UserLabel(this);
                case "usertext":
                    return new UserText(this);
            }
            throw new KeyNotFoundException("Could not find a form with that name!");
        }
    }

从此处开始,创建一个普通的UserControl,但在cs代码中将“UserControl”更改为View,并在主机表单中为其添加名称转换,如上所示。这是我创建的两个视图(设计省略) (UserLabel.cs)

    public partial class UserLabel : View
    {
        public UserLabel(IHost host) : base(host)
        {
            InitializeComponent();
        }

        private void SubmitButton_Click(object sender, System.EventArgs e)
        {
            Host.SwitchView("UserText");
        }
    }

(UserText.cs)

    public partial class UserText : View
    {
        public UserText(IHost host) : base(host)
        {
            InitializeComponent();
        }

        private void LoginButton_Click(object sender, EventArgs e)
        {
            Host.SwitchView("UserLabel");
        }
    }

欢迎在评论部分提出有关此设计的问题。

现在我的推荐是什么?如果您需要Windows桌面应用程序,并且不想定位通用应用程序框架,我建议使用WPF。 WikipediaMicrosoft Developer Network(MSDN)都有关于如何开始的很好说明。至于模式,我建议您使用MVVM并从那里继续前进。网上有很多资源。