WinForms:UserPanel首次设置Visible=true时VisibleChanged事件未触发
问题原因
首次点击按钮时,processesControlPanel的Visible属性默认值就是true。当你执行Controls.Add(processesControlPanel)将它添加到Form1的控件集合后,再设置processesControlPanel.Visible = true,属性值并没有发生变更——因为它本来就是true,所以VisibleChanged事件不会被触发。
只有当你先将Visible设为false(比如点击取消按钮),之后再设置为true时,属性值从false变为true,才会触发事件的Visible==true分支。
解决方案
方案1:初始化时将UserPanel设为不可见
在创建processesControlPanel实例的初始化阶段(比如Form1的构造函数),提前把它的Visible设为false:
// Form1初始化代码示例 processesControlPanel = new UserPanel(this); processesControlPanel.Visible = false; // 初始设为不可见
之后在ProccessBtn_Click中添加控件集合后再设置Visible=true,此时属性从false变为true,会正常触发VisibleChanged事件的对应分支。
方案2:添加到控件集合前先设为不可见
修改ProccessBtn_Click方法,在添加控件到集合前设置Visible=false:
private void ProccessBtn_Click(object sender, EventArgs e) { SaveOriginalFormSize(); if (!Controls.Contains(processesControlPanel)) { processesControlPanel.Visible = false; // 添加前设为不可见 processesControlPanel.Location = new Point(0, 41); Controls.Add(processesControlPanel); } processesControlPanel.Visible = true; processesControlPanel.BringToFront(); }
第一次添加后设置Visible=true时,属性值发生变更,事件会正常触发。
方案3:手动触发事件(应急方案,不推荐)
如果不想修改初始化逻辑,可在首次添加控件后手动触发VisibleChanged事件:
private void ProccessBtn_Click(object sender, EventArgs e) { SaveOriginalFormSize(); bool isFirstAdd = !Controls.Contains(processesControlPanel); if (isFirstAdd) { processesControlPanel.Location = new Point(0, 41); Controls.Add(processesControlPanel); // 手动触发可见性变更事件 processesControlPanel.OnVisibleChanged(EventArgs.Empty); } processesControlPanel.Visible = true; processesControlPanel.BringToFront(); }
此方式属于绕过系统原生事件触发逻辑,优先推荐前两种方案。
验证说明
采用前两种方案后,首次点击按钮时,processesControlPanel的Visible属性会经历false到true的明确变更,VisibleChanged事件的Visible==true分支会正常执行,调用form1Reference.DisableKeyboardHook()。
内容的提问来源于stack exchange,提问作者Yordan Voyvode

