【问题标题】:Changing panel control from inside the panel从面板内部更改面板控制
【发布时间】:2017-03-02 13:45:12
【问题描述】:

我正在使用 WinForms 创建一个应用程序。我有panel,其中显示了user control。在这个user control 里面我有一个button。当我单击按钮时,我想清除panel 并显示不同的user control。我正在尝试使用以下代码来做到这一点:

private void btnCreateOffer_Click(object sender, EventArgs e)
{
    var myControl = new WindowsFormsDemo.View.CreateOffer();
    MockUpForm.panMain.Controls.Clear();
    MockUpForm.panMain.Controls.Add(myControl);
}

这适用于直接放置在父窗体中的按钮,但是当我在 user control 中使用时,它会说:

“MockUpForm.panMain”因其保护级别而无法访问

我想这与私有/公共类有关。但我宁愿拥有“正确”的解决方案,而不是仅仅将所有内容都公开。

对这通常如何做有什么建议吗?

【问题讨论】:

  • 这是一种根本错误的方法。相反,引发一个事件,您的主窗体可以订阅它并围绕它的控件摇晃。使用 Controls.Clear() 也是非常非常错误的,非常,您必须在删除的任何控件上调用 Dispose() 方法,否则会导致永久性内存泄漏。
  • 谢谢你们。我对 WinForms 很陌生,所以我很可能做很多事情非常错误:-)。我将研究事件方法...
  • @HansPassant:他没有提到是否要重用已移除的控件。但是如果事件也被订阅处理还不够,内存泄漏还是会发生的。
  • 这不正确,处理删除的控件就足够了。该事件仅具有对表单对象的引用,因此只能使表单对象保持活动状态。它已经是活的了。表单对控件对象的唯一引用存储在 Controls 集合中,Dispose() 将其删除。没有泄漏。
  • panMain.Dispose(); 破坏了面板,这不是您想要的。您应该在面板中处理每个控件,因此请尝试使用 while 循环:while (panMain.Controls.Count > 0) panMain.Controls[0].Dispose();

标签: c# winforms panel


【解决方案1】:

解决方案 1(丑陋):

在设计器中公开panMain

解决方案 2(更好一些):

提供公共方法来安全地完成此类任务:

// MockUpForm code:

public void ClearPanelControls()
{
    panMain.Controls.Clear();
}

public void AddControlToPanel(Control c)
{
    panMain.Controls.Add(c);
}

然后调用这些方法而不是发布整个面板,这使得例如处置整个面板和诸如此类的事情成为可能...

【讨论】:

  • 我无法让 解决方案 2 工作。我无法从用户控件访问主窗体中的方法。即使它们是公开的......?
  • 您能附上一张图片吗?在我看来,您想删除单击的按钮以及面板中的其他控件...
【解决方案2】:

要从UserControl 访问父窗体的控件,您可以使用delegateevent

类似这样的......

Windows 窗体(父窗体)代码....

public Form1()
{
    InitializeComponent();
    userControl1.CreateOffer += UserControl1_CreateOffer;
}

private void UserControl1_CreateOffer()
{
    var myControl = new WindowsFormsDemo.View.CreateOffer();
    this.panMain.Controls.Clear();
    this.panMain.Controls.Add(myControl);
}

用户控制代码...

internal delegate void CreateOfferDelegate();
internal event CreateOfferDelegate CreateOffer;

public UserControl1()
{
    InitializeComponent();
}

private void btnCreateOffer_Click(object sender, EventArgs e)
{
    CreateOffer();
}

【讨论】:

  • 它不喜欢FinancingCalculator.CreateOffer += FinancingCalculator_CreateOffer;这一行。它给出以下错误:非静态字段、方法或属性“FinancingCalculator.CreateOffer”需要对象引用
猜你喜欢
  • 1970-01-01
  • 2014-12-06
  • 2015-02-02
  • 1970-01-01
  • 1970-01-01
  • 2012-01-11
  • 1970-01-01
  • 1970-01-01
  • 2016-12-27
相关资源
最近更新 更多