我需要从另一个类(C#)访问表单控件
在我的表单上,我有一个面板容器,名为“panelShowList” 在我的项目中,我添加了一个新类,如下所示:我需要从另一个类(C#)访问表单控件,c#,C#,在我的表单上,我有一个面板容器,名为“panelShowList” 在我的项目中,我添加了一个新类,如下所示: class myNewClass { private int newPanelPos = 30; private const int spaceBetweenElements = 30; private const int panelWidth = 90; private const int panelHeight = 40; private i
class myNewClass
{
private int newPanelPos = 30;
private const int spaceBetweenElements = 30;
private const int panelWidth = 90;
private const int panelHeight = 40;
private int elementPos = 0;
private ArrayList myPanels = new ArrayList() { };
// some irelevant methods
public void addElementPanels(Panel dataPanel, Panel nextPanel)
{
myPanels.Add(dataPanel);
myPanels.Add(nextPanel);
}
public void displayPanels()
{
foreach (Panel tmp in myPanels)
{
// here i'm stuck
// i need to do something like this :
// myMainForm.panelShowList.Controls.Add(tmp);
// of course this is wrong! but i need a method to acces that control
}
}
}
public void displayPanels()
{
frmMain f = new frmMain();
foreach (Panel tmp in myPanels)
{
f.display(tmp);
// where display(Panel tmp) is a function in my Form, who access
// "panelShowList" control and add a new Panel
}
}
基本上,我需要一种方法将ArrayList中的所有面板添加到表单中的“panelShowList”控件中
我试过这样的方法:
class myNewClass
{
private int newPanelPos = 30;
private const int spaceBetweenElements = 30;
private const int panelWidth = 90;
private const int panelHeight = 40;
private int elementPos = 0;
private ArrayList myPanels = new ArrayList() { };
// some irelevant methods
public void addElementPanels(Panel dataPanel, Panel nextPanel)
{
myPanels.Add(dataPanel);
myPanels.Add(nextPanel);
}
public void displayPanels()
{
foreach (Panel tmp in myPanels)
{
// here i'm stuck
// i need to do something like this :
// myMainForm.panelShowList.Controls.Add(tmp);
// of course this is wrong! but i need a method to acces that control
}
}
}
public void displayPanels()
{
frmMain f = new frmMain();
foreach (Panel tmp in myPanels)
{
f.display(tmp);
// where display(Panel tmp) is a function in my Form, who access
// "panelShowList" control and add a new Panel
}
}
但只有我这样做,它才会起作用:
f.ShowDialog();
另一种形式是开放的
如有任何建议,将不胜感激
另一种形式是开放的
这是因为您正在创建一个全新的表单:
frmMain f = new frmMain();
如果要修改现有表单的状态,则该代码将需要对该表单的引用。有很多方法可以做到这一点。可以简单地传递对该方法的引用:
public void displayPanels(frmMain myMainForm)
{
foreach (Panel tmp in myPanels)
{
// myMainForm.panelShowList.Controls.Add(tmp);
// etc.
}
}
然后,当主窗体调用该方法时,它会提供对自身的引用:
instanceOfNewClass.displayPanels(this);
不过,老实说,现在还不清楚你想要什么样的结构。如果代码正在修改表单,那么我认为代码应该在表单上。它当然可以被组织成一个类,但也许那可以是一个这种形式的内部类,因为没有其他需要知道它
我还担心myNewClass
的实现需要按特定顺序调用方法。对象上的任何给定操作都应该完全封装逻辑以完成该操作。如果对象在逻辑完成之前未处于有效状态,则某些初始化逻辑可能属于构造函数
不过,这只是一个猜测,因为这里的对象结构不清楚。可能有点晚,但无论如何,这里有另一种方法,它仍然比David的方法更清晰: 您应该在
MyNewClass
中添加一个EventHandler。然后您可以从表单中订阅该事件
public partial class Form1 : Form
{
private readonly MyNewClass _myNewClass;
public Form1()
{
InitializeComponent();
_myNewClass = new MyNewClass();
_myNewClass.DisplayPanelsInvoked += DisplayPanelsInvoked;
}
private void DisplayPanelsInvoked(object sender, DisplayPanelsEventArgs e)
{
var panels = e.Panels; // Add the panels somewhere on the UI ;)
}
}
internal class MyNewClass
{
private IList<Panel> _panels = new List<Panel>();
public void AddPanel(Panel panel)
{
_panels.Add(panel);
}
public void DisplayPanels()
{
OnDisplayPanels(new DisplayPanelsEventArgs(_panels));
}
protected virtual void OnDisplayPanels(DisplayPanelsEventArgs e)
{
EventHandler<DisplayPanelsEventArgs> handler = DisplayPanelsInvoked;
if (handler != null)
{
handler(this, e);
}
}
public event EventHandler<DisplayPanelsEventArgs> DisplayPanelsInvoked;
}
internal class DisplayPanelsEventArgs : EventArgs
{
public DisplayPanelsEventArgs(IList<Panel> panels)
{
Panels = panels;
}
public IList<Panel> Panels { get; private set; }
}
表单只有在打开时才存在。所以,当它未打开时,不访问它是正常的。要修复它,您需要创建一个静态对象并将表单存储在其中。所以你可以在它关闭时访问它。@vgSefa:这本质上是使用静态值作为全局变量,这是一种非常糟糕的使用模式。保持值的范围比将它们转储到某个地方让所有人都看到要好。此外,您的第一个声明(“表单只有在打开时才存在”)显然是错误的。与任何对象一样,表单对象只要在作用域中就存在。请不要使用
ArrayList
。在这种情况下,最好使用通用列表:private IList myPanels=new list()代码>@khlr非常感谢您的建议。我没有任何C#方面的经验,所以我仍在学习很多。