4

多くの子コントロールで構成されるユーザーコントロールがあり、ユーザーコントロールのダブルクリックイベントを処理する必要があります。そこで、イベントハンドラーを追加しましたが、トリガーされることはありません。

私が見つけた最も簡単な解決策は、子のコントロールを繰り返し処理し、ダブルクリックイベントをサブスクライブすることです。これは本当に正しい方法ですか?より良い方法はありますか?ありがとうございました。

4

2 に答える 2

6

以下は、ユーザーコントロールに追加されている第1レベルの子コントロールに対してのみ機能します。これらの子に後で追加されるコントロールでは機能しません。たとえば、第1レベルのPanel子コントロールをダブルクリックしても機能しますLabelが、パネルに追加されたコントロールでは機能しません。

Test.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);
    }
}

他のケースに対処するために、コントロール内にコントロールが含まれている場合は、次のコードを使用できます。他の子コントロールを追加する前に、必ずユーザーコントロールをその親コン​​トロールに追加してください。これを行ったら、コントロール階層を下るのと同じ原則に従います。

簡単に言うと、コントロール階層のどこかにコントロールを追加する前に、その親がコントロールコレクションにすでに追加されていることを確認してください。

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を作成するには、(パネル)親コントロールと多くの子コントロール(内)を使用すると便利です。たとえば、多くのラベル(子供)を持つ1つのパネル(親)。

このコードは、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 に答える