我要制作的程序涉及一种主要形式,该形式应该能够在5个不同的菜单之间切换。对Form.cs
文件中的所有功能进行编程将使它成为一个非常长的类,因此我想做的是从另一个类调用Panel以添加控件元素并从MySQL数据库加载所有数据,具体取决于菜单已选择。
更具体地说,我有ParentInterface.cs
,我想在其中显示动态面板中的ChoreUI,该面板将在名为ChoreUI.cs
的新类中进行修改。
我尝试使ChoreUI从ParentInterface继承,并使其成为目标。尽管我对Windows窗体的了解不足,但仍然是这样。
ParentInterface.cs
namespace ChoreApplication.UI{
public partial class ParentInterface : Form
{
private ChoreUI ChoreUI;
private ParentInterface PUI;
public ParentInterface()
{
ChoreUI = new ChoreUI(PUI);
InitializeComponent();
}
private void ChoreNavButton_Click(object sender, EventArgs e)
{
var ChoreUI = new ChoreUI(PUI);
ChoreUI.DillerDaller();
}
}
ChoreUI.cs
namespace ChoreApplication.UI
{
class ChoreUI
{
public ParentInterface PUI;
public ChoreUI(ParentInterface PUI)
{
this.PUI = PUI;
}
public void DillerDaller()
{
PUI.dynamicPanel.Controls.Add(new Label { Location = new Point(10, 10), Name="textName", Text = "hello"});
}
}
我希望能够从ChoreUI
类而不是ParentInterface
类中向面板添加新的控件元素。但是到目前为止,我还没有成功。
答案 0 :(得分:1)
您目前所拥有的并不是不好,您的子组件具有对父代的引用,没关系。
但是,这就是问题
public void DillerDaller()
{
PUI.dynamicPanel.Controls.Add(new Label { Location = new Point(10, 10), Name="textName", Text = "hello"});
}
在基本级别上,您违反了封装原则,其中dynamicPanel
在表单内部为protected
,因此无法从外部访问它。从主表单中继承子组件 不是正确的解决方案。
在更高层次上,您在这里违反了所谓的 Demeter法,其中不应误用组件的内部实现细节。将dynamicPanel
的可见性更改为public
将无济于事。相反,规则说您应该使用稳定的接口包装此类实现细节
public partial class ParentInterface : Form
{
...
public void AddDynamicPanelControl( Control control ) {
this.dynamicPanel.Controls.Add( control );
}
public void RemoveDynamicPanelControl( Control control ) {
this.dynamicPanel.Controls.Remove( control );
}
}
并使用新引入的界面
public void DillerDaller()
{
var label = new Label { Location = new Point(10, 10), Name="textName", Text = "hello"};
this.PUI.AddDynamicPanelControl( label );
// if you store the reference to the label somewhere,
// you'll be able to call `Remove....` to remove this control from
// the form
}