【问题标题】:Visual Studio : Linking User Control and FormVisual Studio:链接用户控件和表单
【发布时间】:2019-10-16 11:16:18
【问题描述】:

我创建了由两个窗口组成的仪表板 - 主屏幕(表单)和数据屏幕(用户控件)。 我的主屏幕是仪表板,单击仪表板上的“数据”按钮后,用户将被发送到数据屏幕(他在其中输入他的详细信息)。我在两个窗口之间进行这种转换的方式是使数据屏幕可见并在按下数据按钮时将其置于前面。

第一季度。这是切换窗口的正确方法吗?有没有更好的方法来做到这一点?

来到主要问题,仪表板指示用户是否输入了数据,如果是,则显示用户数据。获取用户数据的代码写在用户控件中。现在我希望将此数据发送到主屏幕(表单),以便可以在仪表板上显示数据。

第二季度。如何链接用户控件和表单 - 变量明智?如何在表单和用户控件之间建立双向通信,即用户控件应该能够读取表单的变量,表单应该能够读取用户控件的变量

【问题讨论】:

  • 一般来说,在 UserControl 的 Constructor 中,使其接收对 Form 的引用。在 UserControl 中,声明一个类型与您的主窗体匹配的变量,并在 UserControl 构造函数中设置它。现在 UserControl 具有对主窗体的引用。主窗体已经引用了用户控件,因为它是主窗体(假设主窗体以某种方式包含用户控件)。如果您在设计时创建 UserControl,那么构造函数方法将不起作用。相反,使用一个属性来接收主窗体并在窗体的 Load() 事件中设置它。
  • 我在主窗体中创建了一个用户控件对象,现在我可以在主窗体中访问用户控件的变量。但是如何在用户控件中访问表单的变量呢?即如何访问子类中的父类变量
  • 关于问题 1,这完全取决于您。只有您可以决定什么最适合您的应用程序。在我们提出其他方法之前,我们需要更多信息......
  • 信息之类的?我正在为我构建的硬件项目开发 GUI。数据通过串行端口发送到 GUI。 GUI 只需获取数据,将其隔离并显示在所需的位置。 GUI(表单)上有一个主页,此页面上有各种按钮。当用户点击这些按钮时,他会被引导到不同的页面(用户控件)
  • 如果您一次只希望一个 UserControl 可见,那么您所做的一切都很好。如果您希望一次显示多个 UserControl,请考虑使用 TabControl 并在其中显示您的 UserControl。

标签: c# vb.net visual-studio-2015 dashboard


【解决方案1】:

这里有两种方法...


紧耦合

在 UserControlA 中,我声明了 Form1 类型的属性(父窗体):

public partial class UserControlA : UserControl
{

    public UserControlA()
    {
        InitializeComponent();
    }

    private Form1 f1;
    public Form1 F1
    {
        get { return f1; }
        set { f1 = value; }
    }

    private void foo()
    {
        if (f1 != null)
        {
            // ... do something with "f1" ...
        }
    }

}

然后,在 Form1 中,我在 Load() 事件中设置该属性:

public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        userControlA1.F1 = this;
    }

}

这是紧密耦合的,因为现在 UserControlA 具有对 Form1 的硬编码引用。这使得它可以很好地与 Form1 一起工作,但现在不太灵活,因为它不能很好地与任何其他表单一起工作。例如,如果您希望这种方法与 Form2 一起使用,那么您必须更改 UserControl 中的硬编码类型。

如果表单和用户控件之间存在非常强的关系,并且用户控件可能不会与任何其他表单或任何其他场景一起使用,请使用此方法。


松散耦合

在 UserControlB 中,我声明了一个事件 (BroadcastName),它将向外界传达一个字符串:

public partial class UserControlB : UserControl
{

    public delegate void dlgBroadcastName(UserControlB source, string name);
    public event dlgBroadcastName BroadcastName;

    public UserControlB()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (BroadcastName != null)
        {
            BroadcastName(this, textBox1.Text);
        }
    }

}

现在,在 Form1 的 Load() 事件中(或使用属性窗格中的闪电图标),我们连接 BroadcastName 事件:

public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        userControlB1.BroadcastName += UserControlB1_BroadcastName;
    }

    private void UserControlB1_BroadcastName(UserControlB source, string name)
    {
        // ... do something to Form1 with the received information in here ...
    }

}

这是松耦合的,因为 UserControlB 不知道它与谁通信。它只是引发它的事件,并且订阅的人都会得到通知。请注意,此 UserControl 可以与任何表单一起使用,无需更改。这通常是一种更灵活的方法,并且当您的用户控件本质上更通用并且将用于更广泛的情况时才有意义。

【讨论】:

  • 如果我在表单中创建一个对象,我可以在用户控件中访问该对象吗?
  • 您是想通过reference直接访问它,还是想通过字符串“按名称”访问它(搜索Controls( )` 为比赛收集)?对于前者,创建一个额外的“setter”方法,就像在紧密耦合的例子中一样,并传递引用。在 UserControl 中,您可以将该引用存储在我的示例中的成员字段中,或者您可以将其存储在某种列表中。对于后一种方法,请使用Controls.Find()
猜你喜欢
  • 2010-11-23
  • 1970-01-01
  • 2016-02-01
  • 2011-08-05
  • 1970-01-01
  • 2020-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多