Force UserControl to activate last active control

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Andrus

    Force UserControl to activate last active control

    I have UserControls in MDI child forms containing TextBoxes and other
    controls.
    When user re-activates form, I need that Control which was last activated is
    activated again.
    Currently *first* control is activated always.

    To reproduce:

    1. Run code.
    2. Make TextBox2 as current TextBox by selecting its text
    3. Activate other form
    4. Activate previous form by clicking in form title bar

    Observed:
    TextBox1 receives focus

    Expected:
    TextBox2 should receive focus

    How to force UserControl to forward focus to child its current child control
    (TextBox2) ?

    Andrus.


    using System.Windows. Forms;
    public class Test
    {
    static void Main()
    {
    Application.Run (new MainForm());
    }
    }

    class MainForm : Form
    {
    public MainForm()
    {
    WindowState = FormWindowState .Maximized;
    IsMdiContainer = true;
    Form frm = new Childform();
    frm.MdiParent = this;
    frm.Show();
    Form frm2 = new Childform();
    frm2.MdiParent = this;
    frm2.Show();
    frm2.Left = 2000;
    }
    }

    class Childform : Form
    {
    public Childform()
    {
    Controls.Add(ne w Mycontrols());
    }
    }

    class Mycontrols : UserControl
    {
    public Mycontrols()
    {
    TextBox tb1 = new TextBox();
    tb1.Text = "TextBox1";
    TextBox tb2 = new TextBox();
    Controls.Add(tb 1);
    tb2.Top = 100;
    tb2.Text = "TextBox2";
    tb2.Select();
    Controls.Add(tb 2);
    }
    }

  • =?Utf-8?B?V2FsdGVyIEZyYW5r?=

    #2
    RE: Force UserControl to activate last active control

    "Andrus" wrote:
    How to force UserControl to forward focus to child its current child control
    (TextBox2) ?
    Hi Andrus,

    remember the active control in your child form and focus it on activation:

    private Control activeControl = null;

    private void ChildForm_Deact ivate(object sender, EventArgs e)
    {
    activeControl = ActiveControl;
    }

    private void ChildForm_Activ ated(object sender, EventArgs e)
    {
    if (activeControl != null)
    activeControl.F ocus();
    }

    you have to do the same in your UserControl!

    Walter

    Comment

    • =?Utf-8?B?V2FsdGVyIEZyYW5r?=

      #3
      RE: Force UserControl to activate last active control

      finished the example, because needed it myself:

      public partial class ChildForm : Form
      {
      Control activeControl = null;
      Control activeUserContr ol = null;

      public ChildForm ()
      {
      InitializeCompo nent();
      }

      private void ChildForm _Deactivate(obj ect sender, EventArgs e)
      {
      activeControl = ActiveControl;
      if (activeControl is IContainerContr ol)
      {
      activeUserContr ol =
      ((IContainerCon trol)activeCont rol).ActiveCont rol;
      }
      else activeUserContr ol = null;
      }

      private void ChildForm _Activated(obje ct sender, EventArgs e)
      {
      if (activeControl != null)
      activeControl.F ocus();
      if (activeUserCont rol != null)
      activeUserContr ol.Focus();
      }
      }


      Walter

      Comment

      • Andrus

        #4
        Re: Force UserControl to activate last active control

        Walter,
        finished the example, because needed it myself:
        Thank you.
        I tried your code with the following form:

        Form contains ToolStripContai ner.
        ToolStripContai ner contents panel contain UserControl and DataGridView.

        For TextBox in UserControl in Activated event probably

        if (activeControl != null)
        activeControl.F ocus();

        activates ToolStripContai ner and

        if (activeUserCont rol != null)
        activeUserContr ol.Focus();

        activates UserControl.

        In this case, this code does not set focus to proper TextBox. I tried also
        to set TextBox in DataGridView as active control. It does not set focus to
        DataGrdiView control also.

        How to use this code with Usercontrol and DataGridView in ToolStripContai ner
        ?

        Andrus.

        Comment

        • =?Utf-8?B?V2FsdGVyIEZyYW5r?=

          #5
          Re: Force UserControl to activate last active control

          Hi Andrus
          Form contains ToolStripContai ner.
          Just change

          activeControl = toolStripContai ner1.ActiveCont rol;

          in ChildForm_Deact ivate event.

          Walter

          Comment

          • =?Utf-8?B?V2FsdGVyIEZyYW5r?=

            #6
            Re: Force UserControl to activate last active control

            one last more general approach:

            Control activeControl = null;

            private void ChildForm_Deact ivate(object sender, EventArgs e)
            {
            activeControl = this.ActiveCont rol;
            while (activeControl is IContainerContr ol)
            activeControl =
            ((IContainerCon trol)activeCont rol).ActiveCont rol;
            }

            private void ChildForm_Activ ated(object sender, EventArgs e)
            {
            if (activeControl != null)
            activeControl.F ocus();
            }

            Walter

            Comment

            • Andrus

              #7
              Re: Force UserControl to activate last active control

              Walter,
              one last more general approach:
              Thank you.
              I tried it in the following form:

              Form contains ToolStripContai ner.
              ToolStripcontai ner body contains UserControl and editable DataGridView
              having editmode EditOnEnter
              DataGridView has DataGridViewTex tBoxColumn added in code.

              When Editable TextBox in this DataGridView has focus, it is not focused on
              form re-activate.
              Focus() returns false for textbox.
              Stepping into Focus() source code shows that this is caused probably because
              TextBox does not have handle created: probably on deactivate
              DataGridView releases TextBox because it has mode which creates edit control
              only when column is activated.

              Any ides how to fix this without changing datagridview edit modes?
              Maybe we should activate grid container control first like in your first
              code ?

              An alternate, untested approach may be:

              Control focusedControl;

              public Form1()
              {
              InitializeCompo nent();
              this.Load += new EventHandler(Fo rm1_Load);
              }

              void Form1_Load(obje ct sender, EventArgs e)
              {
              InitializeFocus Events(this);
              }

              private void InitializeFocus Events(Control control)
              {
              control.GotFocu s += new EventHandler(Co ntrol_GotFocus) ;
              control.LostFoc us += new EventHandler(Co ntrol_LostFocus );
              foreach (Control ctl in control.Control s)
              {
              InitializeFocus Events(ctl);
              }
              return;
              }

              void Control_GotFocu s(object sender, EventArgs e)
              {
              this.focusedCon trol = sender as Control;
              }

              void Control_LostFoc us(object sender, EventArgs e)
              {
              this.focusedCon trol = sender as Control;
              }

              void Form1_LostFocus (object sender, EventArgs e)
              {
              return;
              }

              void Form1_GotFocus( object sender, EventArgs e)
              {
              this.ActiveCont rol = this.focusedCon trol;
              return;
              }

              Andrus.

              Comment

              • Andrus

                #8
                Re: Force UserControl to activate last active control

                I created testcase for it:

                1. Run code.
                2. Enter some data to grid
                3. Click other form caption
                4. Click original form caption
                5. Enter some characters

                Observed: entered characters are ignored

                Expected: entered characters must appear in last cell before form activation

                How to fix ?

                Andrus.

                using System.Windows. Forms;

                public class Test
                {
                static void Main()
                {
                Application.Run (new MainForm());
                }
                }

                class MainForm : Form
                {
                public MainForm()
                {
                WindowState = FormWindowState .Maximized;
                IsMdiContainer = true;
                Form frm = new Childform();
                frm.MdiParent = this;
                frm.Show();
                Form frm2 = new Childform();
                frm2.MdiParent = this;
                frm2.Show();
                frm2.Left = 2000;
                }
                }

                class Childform : Form
                {
                public Childform()
                {
                var grid = new DataGridView();
                grid.Columns.Ad d(new DataGridViewTex tBoxColumn());
                grid.EditMode = DataGridViewEdi tMode.EditOnEnt er;
                Controls.Add(gr id);
                }
                }

                Comment

                Working...