C#使用窗体加载其他用户控件并访问基本控件或属性

3

目前我有一个带有窗体的C#程序,然后将用户控件模板放到该窗体上。用户控件模板实际上只是作为一个占位符使用。我有一系列其他控件,这些控件继承自此用户控件模板。

这些控件中的每一个都有导航按钮,如“继续”和“返回”,并且每个控件都知道需要加载哪个控件。但是,我需要找出更简单的方法来拥有全局于这些控件的变量。

我唯一的解决方法是在加载每个控件时将表单传递给每个控件,并在表单内部使用变量进行读写。有什么正确的方法可以使每个用户控件屏幕都基于包含所有控件均可访问的对象的基本控件构建?

对不起,我的问题表述有些混乱,但我整个早上都在思考这个问题。

以下是一些代码:

我编写的大部分内容都是基于隐藏和显示用户控件,以便在导航期间不会丢失控件中的内容。随着时间的推移,我不需要这样做,因为它最终将从数据库加载数据字段。

代码用于从窗体单击最初加载控件:

        conTemplate1.Controls.Clear();
        conInbound Inbound = new conInbound(this);
        Inbound.Dock = DockStyle.Fill;
        Inbound.Anchor = (AnchorStyles.Left | AnchorStyles.Top);
        conTemplate1.Controls.Add(Inbound);

一个控件中继续按钮的代码:

    if ((Parent.Controls.Count - 1) <= Parent.Controls.IndexOf(this))
        {
            UserControl nextControl = new conPartialClear();
            nextControl.Dock = DockStyle.Fill;
            Parent.Controls.Add(nextControl);
            this.Hide();
            Parent.Controls[Parent.Controls.IndexOf(this) + 1].Show();
        }
        else
        {
            this.Hide();
            Parent.Controls[Parent.Controls.IndexOf(this) + 1].Show();
        }

2个回答

2
从控件到父窗体的最佳通信方法是使用事件,而从父窗体到控件的通信方法是调用方法。
但是,如果您不想或不能遵循这种做法,以下是我的建议。
每个UserControl都有一个ParentForm属性,返回包含该控件的窗体。 如果您知道UserControl将始终连接到MyParentForm,则只需转换ParentForm,然后就可以访问所有公共控件、方法等。
这是我的意思:
public class conTemplate
{
    public MyParentForm MyParentForm
    {
        get
        {
            return (MyParentForm)this.ParentForm;
        }
    }
}

这样,您可以轻松访问MyParentForm的任何公共成员。您的conInbound类可以包含类似于this.MyParentForm.GlobalSettings.etc...的代码,并且甚至可以访问任何公共控件。


我相信你的快速修复方法会起作用。然而,我想遵循最佳实践。我在表单内创建了方法,但是大问题是用户控件直到运行时才实际上位于表单上。因此,在设计时,当我尝试访问表单中的方法时,它尚未看到表单,因此无法访问其属性。为了实现这种链接,我需要做什么? - bigphildogg86
我刚刚意识到另一个问题是我的conTemplate在另一个类库中。我试图将其与主应用程序分开。看起来我可能需要将模板带入我的主类库,或者在我的类库中创建一个通用的用户控件模板。我担心这会让一切变得混乱不堪。 - bigphildogg86
是的,目前的设计听起来有点混乱。我做过一个非常类似的项目,我记得发现了这些问题,特别是在设计时依赖方面。我建议将依赖关系作为“conTemplate”的属性。您的表单可以在运行时创建依赖项并将其分配给每个“conTemplate”实例。这是共享控件之间依赖关系的好方法,但控件不需要知道容器的任何信息。对于设计时间,如果必要,您可以创建一个“虚拟”的依赖项。但要小心,设计师不要序列化它。 - Scott Rippey

0

我不太确定我理解你的问题。听起来你想让用户控件与其父窗体“做些什么”。如果是这样,你可能需要考虑在UC中添加事件,然后在窗体本身上处理它们。

基本上,对于你的UC的“继续”按钮,当按下时会触发一个事件。你需要在你的窗体中处理它。我不太确定从记忆中的语法,否则我会为你编写一些代码。但我认为这是你要采取的路线。把你的UC看作任何其他Windows窗体控件。如果你在窗体上添加一个按钮,你会分配它的事件方法。对UC也是一样的。

我找到了这个链接,认为它可能有帮助。向下滚动到它谈论UC和事件的地方。 http://www.akadia.com/services/dotnet_user_controls.html

希望这可以帮助你。

根据OP提供的新信息进行编辑。

如果我理解正确,你可以在UC内声明一个类型为yourForm的全局变量,然后在运行时将该变量设置为ParentForm。

所以,在你的UC类内部,你可以这样做:

private parentFormInstance;

然后在UC的构造函数内,您可以将其设置为:

parentFormInstance = this.ParentForm;(或者任何属性名称)。

这允许您在设计时使用:

parentFormInstance.DoSomething();

不要让编译器对你大喊大叫。

这只是基本建议,但如果你能回头让自己更轻松一些,即使需要重新调整一些东西并花费额外的时间,也是值得的。这可能会在长远节省你的时间。


事件可能会让我更接近我想做的事情。我也评论了Scott Rippey的答案。我正在寻找一种从表单上的用户控件访问变量的方法。触发事件很可能会使我的导航更易管理。我正在尝试思考的最大问题是,如果我在运行时将控件放到表单上,那么如何在设计时访问变量而没有这个关联?Scott给出了一个快速解决方法,但我也想遵循良好的实践。 - bigphildogg86

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接