示例#1
0
 internal void FocusActiveControlInternal()
 {
     if (active_control != null && active_control.Visible)
     {
         // Avoid focus loops, especially with ComboBoxes, on Win98/ME.
         IntPtr focusHandle = XplatUI.GetFocus();
         if (focusHandle == IntPtr.Zero || Control.FromChildHandle(focusHandle) != active_control)
         {
             XplatUI.SetFocus(active_control.Handle);
         }
     }
     else
     {
         // Determine and focus closest visible parent
         ContainerControl cc = this;
         using (_ = new Focusing()) {
             while (cc != null && !cc.Visible)
             {
                 Control parent = cc.Parent;
                 if (parent != null)
                 {
                     cc = parent.GetContainerControl() as ContainerControl;
                 }
                 else
                 {
                     break;
                 }
             }
         }
         if (cc != null && cc.Visible)
         {
             XplatUI.SetFocus(cc.Handle);
         }
     }
 }
示例#2
0
        protected override bool ProcessDialogKey(Keys keyData)
        {
            bool tabbing = false;

            if ((keyData & (Keys.Alt | Keys.Control)) == Keys.None)
            {
                Keys key = keyData & Keys.KeyCode;
                switch (key)
                {
                case Keys.Tab:
                    tabbing = true;
                    if (ProcessTabKey((keyData & Keys.Shift) == 0))
                    {
                        return(true);
                    }
                    break;

                case Keys.Left:
                case Keys.Right:
                case Keys.Up:
                case Keys.Down:
                    if (ProcessArrowKey(key == Keys.Right || key == Keys.Down))
                    {
                        return(true);
                    }
                    break;
                }
            }
            using (_ = new Focusing(tabbing))
                return(base.ProcessDialogKey(keyData));
        }
示例#3
0
        protected override void Select(bool directed, bool forward)
        {
            using (_ = new Focusing())
            {
                if (Parent != null)
                {
                    IContainerControl parent = Parent.GetContainerControl();
                    if (parent != null)
                    {
                        parent.ActiveControl = this;
                    }
                }

                if (directed && auto_select_child)
                {
                    SelectNextControl(null, forward, true, true, false);
                }
            }
        }
示例#4
0
        internal void SetActiveControl(Control value)
        {
            using (_ = new Focusing())
            {
                if (active_control == value && (value == null || value.Focused))
                {
                    return;
                }

                if (value != null && !Contains(value))
                {
                    throw new ArgumentException("Cannot activate invisible or disabled control.");
                }

                if (value == null)
                {
                    Control previous_active_control = active_control;
                    active_control = null;
                    using (_ = new Focusing(false))
                        previous_active_control?.FireLeave();
                    return;
                }

                // Fire the enter and leave events if possible
                Form      form             = FindForm();
                Control   active           = GetMostDeeplyNestedActiveControl(form == null ? this : form);
                Control   common_ancestor  = GetCommonContainer(active, value);
                ArrayList chain            = new ArrayList();
                ArrayList validation_chain = new ArrayList();
                Control   walk             = active;

                // we split this up into three steps:
                //    1. walk up the tree (if we need to) to our root, firing leave events.
                //    2. validate.
                //    3. walk down the tree (if we need to), firing enter events.

                // "our root" is either the common ancestor of the current active
                // control and the new active control, or the current active control,
                // or the new active control.  That is, it's either one of these three
                // configurations:

                //  (1)     root	    (2)  new          (3)  current
                //          /  \	        /   \		    /   \
                //	  ...   ...	      ...   ...		  ...   ...
                //        /      \	      /	                  \
                //     current   new       current                new


                // note (3) doesn't require any upward walking, and no leave events are generated.
                //      (2) doesn't require any downward walking, and no enter events are generated.

                // as we walk up the tree, we generate a list of all controls which cause
                // validation.  After firing the leave events, we invoke (in order starting from
                // the most deeply nested) their Validating event.  If one sets CancelEventArgs.Cancel
                // to true, we ignore the control the user wanted to set ActiveControl to, and use
                // the Validating control instead.

                bool    fire_enter = true;
                Control root       = common_ancestor;

                active_control = value;

                // Generate the leave messages
                while (walk != common_ancestor && walk != null)
                {
                    if (walk == value)
                    {
                        root       = value;
                        fire_enter = false;
                        break;
                    }
                    using (_ = new Focusing(false))
                        walk.FireLeave();
                    /* clear our idea of the active control as we go back up */
                    if (walk is ContainerControl)
                    {
                        ((ContainerControl)walk).active_control = null;
                    }

                    if (walk.CausesValidation)
                    {
                        validation_chain.Add(walk);
                    }

                    walk = walk.Parent;
                }

                // Validation can be postponed due to all the controls
                // in the enter chain not causing validation. If we don't have any
                // enter chain, it means that the selected control is a child and then
                // we need to validate the controls anyway
                bool    postpone_validation;
                Control topmost_under_root = null;                 // topmost under root, in the *enter* chain
                if (value == root)
                {
                    postpone_validation = false;
                }
                else
                {
                    postpone_validation = true;
                    walk = value;
                    while (walk != root && walk != null)
                    {
                        if (walk.CausesValidation)
                        {
                            postpone_validation = false;
                        }

                        topmost_under_root = walk;
                        walk = walk.Parent;
                    }
                }

                Control failed_validation_control = PerformValidation(form == null ? this : form, postpone_validation,
                                                                      validation_chain, topmost_under_root);
                if (failed_validation_control != null)
                {
                    active_control = value = failed_validation_control;
                    fire_enter     = true;
                }

                if (fire_enter)
                {
                    walk = value;
                    while (walk != root && walk != null)
                    {
                        chain.Add(walk);
                        walk = walk.Parent;
                    }

                    if (root != null && walk == root && !(root is ContainerControl))
                    {
                        chain.Add(walk);
                    }

                    for (int i = chain.Count - 1; i >= 0; i--)
                    {
                        walk = (Control)chain [i];
                        using (_ = new Focusing(false))
                            walk.FireEnter();
                    }
                }

                walk = this;
                Control ctl = this;
                while (walk != null)
                {
                    if (walk.Parent is ContainerControl)
                    {
                        ((ContainerControl)walk.Parent).active_control = ctl;
                        ctl = walk.Parent;
                    }
                    walk = walk.Parent;
                }

                if (this is Form)
                {
                    CheckAcceptButton();
                }

                // Scroll control into view
                ScrollControlIntoView(active_control);


                walk = this;
                ctl  = this;
                while (walk != null)
                {
                    if (walk.Parent is ContainerControl)
                    {
                        ctl = walk.Parent;
                    }
                    walk = walk.Parent;
                }

                // Let the control know it's selected
                if (ctl.ContainsFocus && active_control != null &&
                    (!(active_control is UserControl) || (active_control is UserControl && !((UserControl)active_control).HasFocusableChild())))
                {
                    SendControlFocus(active_control);
                }
            }
        }