繁体   English   中英

我需要从另一个类(C#)访问表单控件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM