为什么从父控件中删除控件会触发VisibilityChanged with Visible = true ?
本文关键字:控件 with VisibilityChanged Visible true 删除 为什么 | 更新日期: 2023-09-27 18:10:42
我正在处理一些遗留代码,我不能引入大的变化。有一个控件具有与OnVisibleChanged
事件相关联的逻辑。
在应用程序生命周期中的某个时刻,控件将从其父控件中删除,当此情况发生时,将触发两次OnVisibileChanged
事件。第一次控件可见度为false
,第二次控件可见度为true
。
为什么会发生这种情况?为什么能见度改变是在第二次触发并且Visible
为真?
复制我描述的行为的简单方法:
创建控件:
class MyButton: Button
{
public MyButton()
{
Text = "Test";
}
protected override void OnVisibleChanged(EventArgs e)
{
base.OnVisibleChanged(e);
MessageBox.Show(string.Format("Im now visible {0}", Visible));
}
}
在表单中使用它,并在otherButton
的on click事件中删除它:
public partial class Form1 : Form
{
private MyButton myButton = new MyButton();
private GroupBox myGroupBox = new GroupBox();
private Button otherButton = new Button();
public Form1()
{
InitializeComponent();
otherButton.Text = "Remove";
otherButton.Click += otherButton_Click;
this.myGroupBox.Controls.Add(myButton);
this.Controls.Add(otherButton);
this.Controls.Add(myGroupBox);
}
void otherButton_Click(object sender, EventArgs e)
{
myGroupBox.Controls.Remove(myButton);
}
}
运行后,如果单击otherButton
,消息将显示两次,第一次可见性将是false
,第二次将是true
。
原因是在本地调用:
[DllImport("user32.dll")]
public static extern IntPtr SetParent(HandleRef hWnd, HandleRef hWndParent);
,在Control.Remove(...)
方法中调用。如果将Controls.Remove(myButton);
替换为SetParent(myButton.Handle, IntPtr.Zero);
,则会触发相同的两个事件。
我的猜测是,当控件从其父控件中删除时,VisibleChanged
事件很方便。然而,控件从未被显式隐藏。因此,第二个调用必须将Visible属性设置回true
。否则,如果按钮被添加回控件,它将不可见。