[英]I need to access a form control from another class (C#)
在我的表单上,我有一个名为“ 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
}
}
}
基本上,我需要一种从窗体上的“ panelShowList”控件上的ArrayList添加所有面板的方法。
我尝试过这样的事情:
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; }
}
我认为这是一个更好的解决方案,因为您不需要为MyNewClass实例提供表单的引用。 因此,这种方法减少了耦合,因为仅表单具有对MyNewClass的依赖。
如果您总是想在添加面板时“更新”表单,则可以删除DisplayPanels
方法并将代码缩短为:
public partial class Form1 : Form
{
private readonly MyNewClass _myNewClass;
public Form1()
{
InitializeComponent();
_myNewClass = new MyNewClass();
_myNewClass.PanelAdded += PanelAdded;
}
private void PanelAdded(object sender, DisplayPanelsEventArgs e)
{
var panels = e.AllPanels; // 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);
OnPanelAdded(new DisplayPanelsEventArgs(_panels, panel)); // raise event, everytime a panel is added
}
protected virtual void OnPanelAdded(DisplayPanelsEventArgs e)
{
EventHandler<DisplayPanelsEventArgs> handler = PanelAdded;
if (handler != null)
{
handler(this, e);
}
}
public event EventHandler<DisplayPanelsEventArgs> PanelAdded;
}
internal class DisplayPanelsEventArgs : EventArgs
{
public DisplayPanelsEventArgs(IList<Panel> allPanels, Panel panelAddedLast)
{
AllPanels = allPanels;
PanelAddedLast = panelAddedLast;
}
public IList<Panel> AllPanels { get; private set; }
public Panel PanelAddedLast { get; private set; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.