在我的表单上,我有一个Panel容器,名为" 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
}
}
}
基本上,我需要一种方法来添加我的ArrayList中的所有面板" panelShowList"从我的形式控制。
我试过这样的事情:
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();
另一种形式是公开的。
任何建议都将受到赞赏。
答案 0 :(得分:1)
另一个表单已打开
那是因为你正在创造一个全新的形式:
frmMain f = new frmMain();
如果要修改现有表单的状态,该代码将需要对该表单的引用。有很多方法可以做到这一点。一种可能是简单地传递对该方法的引用:
public void displayPanels(frmMain myMainForm)
{
foreach (Panel tmp in myPanels)
{
// myMainForm.panelShowList.Controls.Add(tmp);
// etc.
}
}
然后,当您的主窗体调用该方法时,它会提供对自身的引用:
instanceOfNewClass.displayPanels(this);
虽然,老实说,你在这里找到什么样的结构还不是很清楚。如果代码正在修改表单,那么我想代码应该是在该表单上。它当然可以被组织成一个类,但也许它可以是该形式的内部类,因为没有其他东西需要知道它。
我还担心你的myNewClass
实现需要按特定顺序调用方法。对象上的任何给定操作都应完全封装逻辑以完成该操作。如果对象在该逻辑完成之前不处于有效状态,那么某些初始化逻辑可能属于构造函数。
但这有点猜想,因为这里的对象结构并不清楚。
答案 1 :(得分:1)
也许有点晚了,但无论如何,这是另一种方法,它比大卫的方法更清洁:
您应该在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; }
}