【问题标题】:How to access controls on an inherited form?如何访问继承表单上的控件?
【发布时间】:2010-12-17 12:43:05
【问题描述】:

我在我的 winforms 应用程序中使用 DockPanel Suite。 DockContent 类派生自 System.Windows.Forms.Form 类,我的两个表单dockRounds 和dockToolbox 继承自DockContent 类。

这是我第一次这样做,这可能是一个愚蠢的问题,但是在运行时,我如何访问dockRounds 和dockToolbox 表单的控件?

这是我在应用首次运行时加载这两个表单的方式:

public partial class frmMainNew : Form

    clsMWDockPanel mapPanel;
    dockToolbox dockT = new dockToolbox();
    dockRounds dockR = new dockRounds();

    public frmMainNew()
    {
        InitializeComponent();

        dockPanel = new DockPanel();

        SuspendLayout();

        dockPanel.Parent = panelMain;
        dockPanel.Dock = DockStyle.Fill;
        dockPanel.DefaultFloatWindowSize = new Size(108, 528);

        dockPanel.BringToFront();
        dockPanel.BackColor = Color.Transparent;
        dockPanel.DocumentStyle = DocumentStyle.DockingSdi;

        ResumeLayout();

        string error = "Errors:\r\n";
        try
        {
            loadRounds();
            loadToolbox();
        }
        catch (Exception)
        {
            error = error + "The Toolbox and/or Rounds menu could not be created\r\n";
        }

    }

    public void loadToolbox()
    {
        dockT.CloseButton = false;
        dockT.ShowHint = DockState.Float;
        dockT.Text = "Toolbox";
        dockT.BackColor = Color.WhiteSmoke;
        dockT.Icon = this.Icon;
        dockT.Show(dockPanel);
    }

    public void loadRounds()
    {
        if (mapPanel == null)
        {
            CreateMapPanel().Show(dockPanel, DockState.Document);
        }

        mapMain.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
        //mapMain.BringToFront();

        dockR.CloseButton = false;
        dockR.ShowHint = DockState.DockRightAutoHide;
        dockR.Text = "Rounds Menu";
        dockR.BackColor = Color.WhiteSmoke;
        dockR.Icon = this.Icon;
        dockR.Show(dockPanel);
    }

    DockContent CreateMapPanel()
    {
        mapPanel = new clsMWDockPanel();
        mapPanel.ShowHint = DockState.Document;
        mapPanel.Controls.Add(mapMain);

        return mapPanel;
    }

在此先感谢

雷迪

【问题讨论】:

    标签: c# winforms inheritance dockpanel dockpanel-suite


    【解决方案1】:

    您可以使用多种策略来实现不同表单上的对象之间的通信/链接。注意:我在这里的回复不会解决与 DockPanelSuite 相关的任何问题,也不会考虑“辅助”表单之间的区别是“独立的”(即,它们不属于 MainForm“所有”)或制作主窗体的子窗体。这是一个有意识的选择,其基础是相信您所询问的内容与实施中的可能变化无关。

    1. 最简单的策略(如果对很多控件来说很乏味的话)是在辅助窗体中声明公共属性,以公开要从主窗体中操作的控件。例如,假设 Form2 有一个按钮,并且您想在主窗体上处理它的点击事件:

    在 Form2 中定义如下属性:

    public Button form2Button
    {
        get { return button1; }
    }
    

    现在在主窗体的 Load 事件中,假设这是创建 Form2 实例的位置,您可以订阅 Form2 上 Button 的 Click 事件:

    Form2 myForm2;
    Form3 myForm3;
    
    private void Form1_Load(object sender, EventArgs e)
    {
       myForm2 = new Form2();
       myForm2.form2Button.Click += new EventHandler(form2Button_Click);
    
       myForm3 = new Form3();
    }
    

    您可以很容易地想象,在 Form3 中,您有一个使用公共属性公开的 TextBox,就像在 Form2 上公开按钮一样。

    因此,您可以像这样为 Form2 上的按钮单击实现 MainForm 的事件处理程序:

    public void form2Button_Click(object sender, EventArgs e)
    {
        // do something here with the TextBox on Form3 
        // myForm3.theTextBox.Text = 
    }
    

    ...其他策略...

    1. 例如,在您的辅助表单中,按下按钮可以引发一个公共事件,主表单(或任何其他暴露于 Form2 的实体)可以订阅该事件,然后将适当的任何内容发送到适当的目标.

    2. 一般而言,您可以将更高级别的消息传递抽象为一个(可能是静态的)类,发布者在该类中发送消息,并将消息分派给注册的侦听器。

    最后,您可能会对这里的讨论感兴趣:

    Using The Controls Of One Form Into Another

    最好的,

    【讨论】:

    • 谢谢比尔,我已经对此进行了测试,您的第一个建议效果很好-但是,这两种形式有很多控件-有什么方法可以将这些控件的事件代码放入一个单独的类,以免混淆主表单代码,但仍然可以引用控件?再次感谢
    • 请注意,在 .NET FrameWork 3.5、C# 3.0 中,您拥有“自动属性”,可以节省大量输入。 MS 的 Dan Whalin 快速“复习”:weblogs.asp.net/dwahlin/archive/2007/12/04/… 更多详细信息请参阅:msdn.microsoft.com/en-us/library/bb384054.aspx 对于您提出的更广泛的问题,恕我直言,我们需要了解有关您的应用程序的更多信息:是否存在对象连接模式,例如。我正在使用单个静态类作为跨表单同步事件/内容的“调度”中心。最好的,
    【解决方案2】:

    您的类、dockRounds 和 dockToolbox 应该公开您想要访问的任何属性/事件。因此,如果您想连接到控件的事件,请将其路由到公共事件。

    【讨论】:

      【解决方案3】:

      您可以在控件上设置访问修饰符,使其可以随心所欲地访问。默认值为“私人”,这就是您无法从主窗体访问控件的原因。

      在 Visual Studio 的“属性”选项卡上,有一个修饰符属性,用于设置在生成的设计器文件中使用的访问修饰符。

      将此设置为“公共”,您就可以从主窗体访问控件。

      当我从另一个表单继承一个表单时,我刚刚使用了这个。通过将修饰符设置为“受保护”(或“受保护的内部”),我能够访问基类中定义的控件。

      【讨论】:

        【解决方案4】:

        您是否尝试过访问Controls 属性?

        var controls = dockRounds.Controls;
        

        【讨论】:

        • 感谢 Jared - 是的,我可以从主窗体访问控件,但是我如何,例如,使用 dockToolbox 窗体上的按钮的单击事件,更改文本框中的值dockRounds 表格?是否可以在设计时对此进行编码?再次感谢,leddy
        • dockRounds 和 dockToolbox 是兄弟 - 听起来你需要一个静态事件。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-05
        • 2013-03-29
        • 2019-12-23
        • 2011-02-07
        • 1970-01-01
        • 2020-08-08
        • 2010-11-25
        相关资源
        最近更新 更多