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

Posted

技术标签:

【中文标题】C# 使用表单加载其他用户控件并访问基本控件或属性【英文标题】:C# Using a form to load other user controls and have access to a base control or property 【发布时间】:2011-08-29 16:56:50 【问题描述】:

目前我有一个带有 Windows 窗体的 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();
        

【问题讨论】:

Controlling user workflow in Winforms的可能重复 【参考方案1】:

从控件到父控件通信的最佳实践是使用事件,而从父控件到控件通信的最佳实践是调用方法。

但是,如果您不想或不能遵循这种做法,我建议您这样做。

每个UserControl 都有一个ParentForm 属性,该属性返回包含控件的表单。如果您知道UserControl 将始终附加到MyParentForm,您只需转换ParentForm,然后您就可以访问所有公共控件、方法等。

这就是我的意思:

public class conTemplate

    public MyParentForm MyParentForm
    
        get
        
            return (MyParentForm)this.ParentForm;
        
    

这样,您可以轻松访问MyParentForm 的任何公共成员。你的conInbound 类可以有this.MyParentForm.GlobalSettings.etc... 之类的代码,甚至可以访问任何公共控件。

【讨论】:

我相信您的快速修复会奏效。不过,我想遵循最佳实践。我在表单中创建了方法,但最大的问题是用户控件在技术上直到运行时才出现在表单上。因此,在设计时,当我尝试获取表单中的方法时,它还没有看到表单,因此无法访问其属性。为了完成这个链接,我需要做什么? 我刚刚意识到另一个问题是我的 conTemplate 在另一个类库中。我试图将它与主应用程序分开。看起来我可能不得不将模板带入我的主类库或在我的类库中制作一个通用的用户控件模板。恐怕我把这弄得乱七八糟了。 是的,目前的设计听起来有点乱。我做了一个非常相似的项目,我记得发现了这些相同的问题,尤其是在设计时依赖项方面。我建议将依赖项作为conTemplate 的属性。您的表单可以创建依赖项并在运行时将其分配给每个 conTemplate 实例。这是在控件之间共享依赖关系的好方法,但控件不需要了解有关容器的任何信息。对于设计时,如有必要,您可以创建一个“虚拟”依赖项。但请注意设计器不会对其进行序列化。【参考方案2】:

我不确定我是否理解您的问题。听起来您希望用户控件对其父表单“做某事”。如果是这种情况,您可能需要考虑将事件添加到 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 给出了一个快速的解决方法,但我也想遵循良好的做法。

以上是关于C# 使用表单加载其他用户控件并访问基本控件或属性的主要内容,如果未能解决你的问题,请参考以下文章

访问子窗体未绑定控件#Error

创建自定义控件并将其加载到 FormView

如何在 C# 中隐藏包含用户控件的表单?

保存用户控件属性并重新加载

C# winform中使用动态加载控件的属性

获取父用户控件WPF C#的名称