如何在处置/删除控件后重新加载控件

问题描述 投票:0回答:3

所以我想制作一个包含动态控件布局的程序,有点类似于网页。 我有一个特定的按钮,如果您单击它,它应该会处理所有当前可见的控件,并使用第二个 InitializeComponent 加载一组完整的新控件。

第二个页面将包含一个“后退”按钮,该按钮应该用于处理第二组控件,并再次使用第一个 InitializeComponent 重新加载原始控件,这样我就有了 2 个不同的可访问“页面”。

但是,每次我通过按钮切换并再次调用InitializeComponent时,VRAM使用量都会稳步增加,可能是因为它并没有真正通过dispose“杀死”所有以前的资源。

所以我想问是否有一种方法可以重新加载已处理的初始化控件,而不必再次初始化它们。

提前致谢。

编辑: 啊,没关系,我明白了。

而不是 .dispose 我只是使用 Controls.Remove 命令在更改到第 2 页时删除当前的控件集。 如果我想返回,我现在可以简单地使用 Controls.Add 命令再次查看第一组控件,并且 VRAM 使用量不会增加。

这对于处置来说是不可能的,有人愿意解释一下吗?我是 csharp 的真正初学者,基本上是几天前开始的。

c# controls dispose reload
3个回答
1
投票

实际上你不应该自己调用Dispose()。通常,当您在表单上调用 Close() 等时,框架会为您执行此操作。 显然,如果仍然存在对各个元素的引用,这并不总是会导致相应元素被删除。这就是您的控件在某种程度上仍然存在的原因。

如果您(由于某种原因)需要 Close() 或 Remove() 以及您保留引用的元素,您应该在执行其他操作之前执行 element.IsDispose 检查。如果这是真的,你应该重新创建它,因为该元素已经半死了。请不要使用死灵术:-)


0
投票

在任何一次性对象上调用

Dispose
应导致其释放(将引用设置为 null)任何引用的一次性对象,并清理任何直接引用的非托管资源。对于 UI 控件,处置将释放非托管的底层 Win32 GUI 对象。 Dispose 并不是释放内存以供重用,这是当对象没有被某些静态或堆栈(本地)引用(间接)引用时由垃圾收集器完成的。如果您保留对最后一页(要返回)的引用,则其 Controls 集合中的控件仍将被引用并保持活动状态。

即使它们从控件集合中删除并且未被引用,由于 UI 控件往往会存在一段时间,它们很可能已经从第 0 代(经常收集)转移到第 1 代甚至第 2 代(很少收集)。除非存在内存压力(您的系统没有太多可用内存),否则可能需要很长时间才能收集它们。

您可以通过使用带有 SOS 扩展的 WinDbg 查看特定对象所在的世代(甚至列出该世代中的所有对象),或者通过强制完整集合来演示这一点。

强制收集不是

真正的解决方案,但会证明这不是问题,当进程需要空闲内存时它们将被释放,然后垃圾收集器将进行完整收集。

希望可以帮助到有需要的人

0
投票
我所做的是一种反复试验的方法,通过该方法,我可以在执行

Control.Dispose();

功能后重新加载控件。

这是一个基本的方法,但对我来说确实有效。

首先,

this.InitializeComponent();

方法将控件重新加载到窗体中,因此每次使用它时,控件都会重新加载到窗体中,使得控件的数量等于每次使用时增加的控件数量。

现在我能够获得的解决方案是实现一个void函数,其中控件的加载就像表单的设计一样(我从设计代码中的Control中获取了所有信息并将其放入一个void函数中)

所以如下(示例是textBox):

private void newControl(){

this.textBox1 = new System.Windows.Forms.TextBox();;

this.SuspendLayout();

//
// 文本框1
//

this.textBox1.Location = new System.Drawing.Point(X, Y);

this.textBox1.Name = "textBox1";

this.textBox1.Size = new System.Drawing.Size(Length, Width);
this.textBox1.TabIndex = int;
this.textBox1.Click += new System.EventHandler(this.textBox1_Click);

this.Controls.Add(this.textBox1);

this.PerformLayout();


}


control.Dispose()之后的方法中的实现是这样的:

private void button1_Click(object sender, EventArgs e){

textBox1.Dispose();

newControl();
}

    

© www.soinside.com 2019 - 2024. All rights reserved.