c#在相同形式的接口之间切换
本文关键字:接口 之间 | 更新日期: 2023-09-27 18:14:36
我用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();
}
}
}
这种意识形态是创造UI的"最佳"方式吗?是否有一种更有效的方式来移动用户界面,同时保持原始的形式?
不要让表单显示表单,更不要让表单决定显示哪个面板,因为这样很难从代码中正确地跟踪应用程序中的窗口。是的,你可以遍历Application.OpenForms
或someContainer.Controls
来找到你想要的,但你不会想要那样。
您需要应用设计模式,如MVP, MVVM, MVC或应用程序控制器。
在这个答案中解释这些模式会让它有点长(我可能稍后会尝试),但是尝试搜索提到的术语。
也许您应该将表单的职责与用户控件的职责分开,并且在控件中保留对主表单的引用可能会有所帮助
UserControl1 myControl1 = new UserControl1 { MainForm = this };
这只是一个学习示例的建议,也许你应该搜索一个UI设计模式,以便做一些更详细的东西
这个问题是关于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。维基百科和微软开发者网络(MSDN)都有很好的入门指南。至于模式,我建议您使用MVVM并从那里继续。网上有很多资源。