C# 动态面板子面板事件循环错误

C# Dynamic Panel SubPanel-Event Loop bug

我目前正在使用 visual studio 19 中的流布局面板制作 UI。 如果我按下一个按钮,它会使用

克隆一个面板
public static T Clone<T>(this T controlToClone) where T : Control
    {
        PropertyInfo[] controlProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

        T instance = Activator.CreateInstance<T>();
        foreach (PropertyInfo propInfo in controlProperties)
        {
            if (propInfo.CanWrite)
            {
                if (propInfo.Name != "WindowTarget")
                    propInfo.SetValue(instance, propInfo.GetValue(controlToClone, null), null);
            }
        }

        return instance;
    }

在同一个新闻事件中它触发 AddNewPanel("name");

private void AddPanel(string name)
        {
            var label = new Label();
            label.AutoSize = false;
            label.TextAlign = ContentAlignment.MiddleCenter;
            label.Dock = DockStyle.Fill;
            label.Text = name;
            label.MouseEnter += labelEnter;
            label.MouseLeave += labelLeave;

            var panel = panel1.Clone();
            var button = button1.Clone();
            button.Name = "button" + new Random().Next(1, 100);

            panel.Controls.Add(button);
            panel.Controls.Add(label);

            flowLayoutPanel1.Controls.Add(panel);
        }

事件 labelEnter 触发 ShowButtons()

private void showButtons()
        {
            foreach (Control item in flowLayoutPanel1.Controls)
            {
                var button = item.Controls[1];
                button.Visible = true;
            }
        }

除了将 Visible 变为 false 之外,mouseLeave 事件也做同样的事情。

现在我有经验,将控件动态添加到面板,然后将其添加到流布局面板会导致一些问题。例如,labelMouseEnter/Leave 事件在将鼠标移到按钮上时循环。有没有人以前经历过这个或类似的帖子?当按钮最初是 Visible 时不会发生,这意味着 Visible 在设计器视图中变为 true。它用可见属性克隆它。

解决方案是在 MouseLeave 事件中添加一个检查,如下所示:

 private void control_MouseLeave(object sender, EventArgs e)
        {
            var control = sender as Control;
            if (control.ClientRectangle.Contains(control.PointToClient(Cursor.Position))) return;
            //rest 
            ShowButtons();
        }