C# – Windows Forms Controls in a ScrollableControl and Events

ccontrolseventswinforms

I have noticed that the Click event, or other control behaviour, is not always fired when a control contained in a ScrollableControl (Panel, etc) is clicked on.

If the control being clicked doesn't have the focus and is only partially visible it is scrolled into view. This is what I am expecting, however the Click event doesn't get fired or other control behaviour doesn't occur.

If the control already has the focus and is only partially visible the events do get fired.

Checkbox – Scrolls into view, checked state does not change.
CheckedListBox – Scrolls into view, clicked item does not get selected.
TreeView – Scrolls into view, clicked node does not get selected.
Button – Scrolls into view, click event does not get raised.

To reproduce this you can do the following:

  1. Add any of the above controls to a
    Panel
  2. Add an event handler for Click, SelectedItemChanged, etc
  3. Resize the form so that scrollbars are visible on the panel
  4. Scroll the panel so one of the controls is partially visible
  5. Click the partially visible control

Is there any way to ensure the events get fired?

Best Answer

David,

It worked for me.

Code in Form1.Designer.cs:

namespace WindowsFormsApplication1
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.panel1 = new System.Windows.Forms.Panel();
            this.textBox2 = new System.Windows.Forms.TextBox();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.panel1.SuspendLayout();
            this.SuspendLayout();
            // 
            // panel1
            // 
            this.panel1.AutoScroll = true;
            this.panel1.Controls.Add(this.textBox2);
            this.panel1.Controls.Add(this.textBox1);
            this.panel1.Location = new System.Drawing.Point(86, 75);
            this.panel1.Name = "panel1";
            this.panel1.Size = new System.Drawing.Size(176, 70);
            this.panel1.TabIndex = 0;
            // 
            // textBox2
            // 
            this.textBox2.Location = new System.Drawing.Point(109, 17);
            this.textBox2.Name = "textBox2";
            this.textBox2.Size = new System.Drawing.Size(100, 20);
            this.textBox2.TabIndex = 1;
            this.textBox2.Click += new System.EventHandler(this.textBox2_Click);
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(3, 17);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(100, 20);
            this.textBox1.TabIndex = 0;
            this.textBox1.Click += new System.EventHandler(this.textBox1_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(493, 271);
            this.Controls.Add(this.panel1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.panel1.ResumeLayout(false);
            this.panel1.PerformLayout();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Panel panel1;
        private System.Windows.Forms.TextBox textBox2;
        private System.Windows.Forms.TextBox textBox1;
    }
}

Code in Form1.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

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

        private void textBox1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Click1");
        }

        private void textBox2_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Click2");
        }
    }
}