4

我有一个由许多子控件组成的用户控件,我需要处理用户控件的双击事件。所以我添加了事件处理程序,但它从未被触发。

我发现最快的解决方案是遍历子控件并订阅它们的双击事件。这真的是正确的方法吗?有没有更好的方法?谢谢你。

4

2 回答 2

6

以下仅适用于添加到用户控件的第一级子控件。它不适用于随后添加到这些子项的控件。例如,它适用于双击第一级Panel子控件,但不适用于Label添加到面板的子控件。

测试.cs

public partial class Test : UserControl
{
    public Test()
    {
        InitializeComponent();
    }

    protected override void OnControlAdded(ControlEventArgs e)
    {
        e.Control.DoubleClick += Control_DoubleClick;
        base.OnControlAdded(e);
    }

    void Control_DoubleClick(object sender, EventArgs e)
    {
        MessageBox.Show("User control clicked");
        OnDoubleClick(e);
    }
}

Form1.cs

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        var test = new Test();
        var label = new Label();
        label.Text = "test";
        test.Controls.Add(label);
        Controls.Add(test);
    }
}

要解决另一种情况,当控件中包含控件时,可以使用以下代码。在向其添加任何其他子控件之前,请确保将用户控件添加到其父控件。完成此操作后,请遵循与控制层次结构相同的原则。

更简单地说,在控件层次结构中的任何位置添加控件之前,请确保它的父级已添加到控件集合中。

测试.cs

protected override void OnControlAdded(ControlEventArgs e)
{
    e.Control.DoubleClick += Control_DoubleClick;
    e.Control.ControlAdded += OnControlAdded; // add this line
    base.OnControlAdded(e);
}

// add this method
private void OnControlAdded(object sender, ControlEventArgs e)
{
    e.Control.DoubleClick += Control_DoubleClick;
    e.Control.ControlAdded += OnControlAdded;
}

Form1.cs

private void Form1_Load(object sender, EventArgs e)
{
    var test = new Test();
    var panel1 = new Panel();
    panel1.BackColor = Color.AliceBlue;
    var panel2 = new Panel();
    panel2.BackColor = Color.AntiqueWhite;

    var label1 = new Label();
    label1.Text = "test 1";
    label1.BackColor = Color.Aquamarine;

    var label2 = new Label();
    label2.Text = "test 2";
    label2.BackColor = Color.Azure;

    // !!! order is important !!!
    // first add at least one child control to the test control

    // this works as expected
    //Controls.Add(test);
    //test.Controls.Add(panel1);
    //panel1.Controls.Add(panel2);
    //panel2.Left = 50;
    //panel1.Controls.Add(label1);
    //panel2.Controls.Add(label2);

    // this works as expected
    //test.Controls.Add(panel1);
    //Controls.Add(test);
    //panel1.Controls.Add(panel2);
    //panel2.Left = 50;
    //panel1.Controls.Add(label1);
    //panel2.Controls.Add(label2);

    // this doesn't work for panel2 and it's children
    Controls.Add(test);
    panel1.Controls.Add(panel2); // panel2 & children will not trigger the events

    // all controls added to control collections 
    // prior to this line will not trigger the event
    test.Controls.Add(panel1); 

    panel2.Left = 50;
    panel1.Controls.Add(label1);
    panel2.Controls.Add(label2); // will not trigger the event
}
于 2013-01-18T15:37:45.007 回答
1

要创建一个漂亮的 UI,使用(面板)父控件和许多子控件(内部)很有帮助。例如,一个面板(父级)带有许多标签(子级)。

当我想将 MouseEnter 事件(和任何其他事件)添加到特定父控件及其所有子控件时,我会使用此代码。

当您从面板和标签构建自己的按钮以及将其作为单个控件处理以处理 MouseOver 或其他东西时,它是完美的。

我还添加了一些将 MouseEnter 事件(和任何其他事件)添加到所有其他控件及其子控件的代码。希望它可以帮助某人...

// ------------ WINDOWS FORM'S CLASS ------------------------------------
public partial class WFEvent : Form
{

    // ------------ CONSTRUCTOR -----------------------------------------
    public WFEvent()
    {
        // Create Events for Control
        CreateEventsControl(pnlParent);

        // Create Events for Other Controls
        CreateEventsOtherControls(this);
    }

    // ------------ PRIVATE METHODS -------------------------------------
    // Create Events for Parent Control (e.g. a Panel) and Child Controls...
    private void CreateEventsControl(Control control)
    {
        // Create Events for Parent Control
        control.MouseEnter += (sender, e) => { CtlMouseEnter(control); };
        control.Click += (sender, e) => { CtlClick(control); };

        // Create Events for Child Controls...
        CreateEventsControlChildControls(control);
    }

    // Create Events for Parent Control's Child Controls...
    private void CreateEventsControlChildControls(Control control)
    {
        foreach (Control childControl in control.Controls)
        {
            // Create Events for Parent Panel's Child Control
            childControl.MouseEnter += (sender, e) => { CtlMouseEnter(control); };
            childControl.Click += (sender, e) => { CtlClick(control); };

            // Create Events for Child Control's Child Controls...
            CreateEventsControlChildControls(childControl);
        }
    }

    // Create Events for Other Control's Parent and Child Controls...
    private void CreateEventsOtherControls(Control control)
    {
        // Create Event for Other Control's Parent Control
        control.MouseEnter += (sender, e) => { CtlOtherMouseEnter(control); };
        //control.Click += (sender, e) => { CtlOtherClick(control); };

        // Create Event for Other Control's Child Control...
        CreateEventsOtherControlsChildControls(control);
    }

    // Create Event for Other Control's Child Controls...
    private void CreateEventsOtherControlsChildControls(Control control)
    {
        foreach (Control childControl in control.Controls)
        {
            if (childControl != pnlParent)
            {
                // Create Events for Other Control's Child Control
                childControl.MouseEnter += (sender, e) => { CtlOtherMouseEnter(control); };
            //childControl.Click += (sender, e) => { CtlOtherClick(control); };

                // Create Events for Other Control's Child Controls's Child Control...
                CreateEventsOtherControlsChildControls(childControl);
            }
        }
    }

    // MouseEnter for Controls
    private void CtlMouseEnter(Control control) 
    {
            Code...
    }

    // Click for Controls
    private void CtlClick(Control control) 
    {
            Code...
    }

    // MouseEnter for Other Controls
    private void CtlOtherMouseEnter(Control control) 
    {
            Code...
    }

    // Click for Other Controls
    //private void CtlOtherClick(Control control) 
    //{
    //        Code...
    //}
}
于 2019-01-19T22:08:44.120 回答