Author: toshok
Date: 2007-01-10 14:28:52 -0500 (Wed, 10 Jan 2007)
New Revision: 70804
Modified:
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ContainerControl.cs
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs
Log:
2007-01-10 Chris Toshok <[EMAIL PROTECTED]>
* ContainerControl.cs (set_ActiveControl): rework this a bit (and
add some nice ascii art pictures and explanation of the process).
(GetMostDeeplyNestedActiveControl): new utility function we need
because our ActiveControl can refer to a child container with its
own ActiveControl.
* Form.cs (OnActivated): remove the call to SelectActiveControl
from here, since you can override this method and not chain up,
and winforms still sets the active control.
(OnCreateControl): also remove the unnecessary SelectActiveControl
call from here.
(WndProc): it's actually called from the WM_ACTIVATE block, just
before calling OnActivated.
* Control.cs (Select (Control)): move the call to XplatUI.SetFocus
inside the else. the ActiveControl setter will end up setting
focus on @control. This keeps us from setting it again (and
generating an extra LostFocus/GotFocus pair).
(Select (bool, bool)): reindent.
Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
2007-01-10 19:27:11 UTC (rev 70803)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
2007-01-10 19:28:52 UTC (rev 70804)
@@ -1,3 +1,25 @@
+2007-01-10 Chris Toshok <[EMAIL PROTECTED]>
+
+ * ContainerControl.cs (set_ActiveControl): rework this a bit (and
+ add some nice ascii art pictures and explanation of the process).
+ (GetMostDeeplyNestedActiveControl): new utility function we need
+ because our ActiveControl can refer to a child container with its
+ own ActiveControl.
+
+ * Form.cs (OnActivated): remove the call to SelectActiveControl
+ from here, since you can override this method and not chain up,
+ and winforms still sets the active control.
+ (OnCreateControl): also remove the unnecessary SelectActiveControl
+ call from here.
+ (WndProc): it's actually called from the WM_ACTIVATE block, just
+ before calling OnActivated.
+
+ * Control.cs (Select (Control)): move the call to XplatUI.SetFocus
+ inside the else. the ActiveControl setter will end up setting
+ focus on @control. This keeps us from setting it again (and
+ generating an extra LostFocus/GotFocus pair).
+ (Select (bool, bool)): reindent.
+
2007-01-10 Jonathan Pobst <[EMAIL PROTECTED]>
* FlowLayoutPanel.cs, MenuStrip.cs, SplitContainer.cs, SplitterPanel.cs,
Modified:
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ContainerControl.cs
===================================================================
---
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ContainerControl.cs
2007-01-10 19:27:11 UTC (rev 70803)
+++
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ContainerControl.cs
2007-01-10 19:28:52 UTC (rev 70804)
@@ -69,7 +69,7 @@
}
set {
- if (value==null || (active_control == value &&
active_control.has_focus)) {
+ if (value==null || (active_control == value)) {
return;
}
@@ -80,34 +80,83 @@
// Fire the enter and leave events if possible
Form form = FindForm ();
if (form != null) {
- Control active = form.ActiveControl;
- Control common_container =
GetCommonContainer (form.ActiveControl, value);
+ Control active =
GetMostDeeplyNestedActiveControl (form);
+ Control common_container =
GetCommonContainer (active, value);
ArrayList chain = new ArrayList ();
+ ArrayList validation_chain = new
ArrayList ();
Control walk = active;
- // Generate the leave messages
+ // 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
container 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_container;
+
+ // Generate the leave messages
while (walk != common_container) {
+ if (walk == value) {
+ root = value;
+ fire_enter = false;
+ break;
+ }
walk.FireLeave ();
- if (walk.CausesValidation &&
!ValidateControl (walk))
- return;
+ /* 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;
}
- walk = value;
- while (walk != common_container) {
- chain.Add (walk);
- walk = walk.Parent;
+ for (int i = 0; i <
validation_chain.Count; i ++) {
+ if (!ValidateControl
((Control)validation_chain[i])) {
+ value =
(Control)validation_chain[i];
+ fire_enter = true;
+ }
}
- for (int i = chain.Count - 1; i >= 0;
i--) {
- walk = (Control) chain [i];
- walk.FireEnter ();
+ if (fire_enter) {
+ walk = value;
+ while (walk != root) {
+ chain.Add (walk);
+ walk = walk.Parent;
+ }
+
+ for (int i = chain.Count - 1; i
>= 0; i--) {
+ walk = (Control) chain
[i];
+ walk.FireEnter ();
+ }
}
- walk = this.Parent;
+ walk = this;
while (walk != null) {
- if (walk is ContainerControl)
-
((ContainerControl)walk).active_control = this;
+ if (walk.Parent is
ContainerControl)
+
((ContainerControl)walk.Parent).active_control = walk;
walk = walk.Parent;
}
}
@@ -127,10 +176,6 @@
private bool ValidateControl (Control c)
{
- if (c is ContainerControl &&
((ContainerControl)c).ActiveControl != null && !c.ContainerSelected)
- if
(!((ContainerControl)c).ValidateControl(((ContainerControl)c).ActiveControl))
- return false;
-
CancelEventArgs e = new CancelEventArgs ();
c.FireValidating (e);
@@ -142,6 +187,17 @@
return true;
}
+ private Control GetMostDeeplyNestedActiveControl
(ContainerControl container)
+ {
+ Control active = container.ActiveControl;
+ while (active is ContainerControl) {
+ if (((ContainerControl)active).ActiveControl ==
null)
+ break;
+ active =
((ContainerControl)active).ActiveControl;
+ }
+ return active;
+ }
+
// Just in a separate method to make debugging a little easier,
// should eventually be rolled into ActiveControl setter
private Control GetCommonContainer (Control active_control,
Control value)
@@ -190,7 +246,7 @@
if (auto_scale_dimensions.IsEmpty) {
return new SizeF(1f, 1f);
}
- return new
SizeF(CurrentAutoScaleDimensions.Width / auto_scale_dimensions.Width,
+ return new
SizeF(CurrentAutoScaleDimensions.Width / auto_scale_dimensions.Width,
CurrentAutoScaleDimensions.Height /
auto_scale_dimensions.Height);
}
}
@@ -315,7 +371,7 @@
base.Dispose(disposing);
}
- // LAMESPEC This used to be documented, but it's not in code
+ // LAMESPEC This used to be documented, but it's not in code
// and no longer listed in MSDN2
// [EditorBrowsable (EditorBrowsableState.Advanced)]
// protected override void OnControlRemoved(ControlEventArgs e)
{
@@ -380,7 +436,7 @@
return true;
}
break;
- }
+ }
}
@@ -409,7 +465,7 @@
wrapped = true;
}
} while (c != active_control);
-
+
return false;
}
@@ -441,18 +497,22 @@
[EditorBrowsable (EditorBrowsableState.Advanced)]
protected override void WndProc(ref Message m) {
switch ((Msg) m.Msg) {
-
+
case Msg.WM_LBUTTONDOWN:
- OnMouseDown (new MouseEventArgs
(FromParamToMouseButtons ((int) m.WParam.ToInt32()),
+ OnMouseDown (new MouseEventArgs
(FromParamToMouseButtons ((int) m.WParam.ToInt32()),
mouse_clicks, LowOrder ((int)
m.LParam.ToInt32 ()),
HighOrder ((int)
m.LParam.ToInt32 ()), 0));
break;
-
+
case Msg.WM_SETFOCUS:
if (active_control != null)
Select (active_control);
else
+ base.WndProc (ref m);
+#if false
+ else
SelectNextControl (null, true,
true, true, false);
+#endif
break;
default:
@@ -468,7 +528,7 @@
// do nothing here, only called if it is a Form
}
#endregion // Internal Methods
-
+
#if NET_2_0
protected override void OnParentChanged (EventArgs e)
{
Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs
2007-01-10 19:27:11 UTC (rev 70803)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Control.cs
2007-01-10 19:28:52 UTC (rev 70804)
@@ -1218,7 +1218,7 @@
if (container != null && (Control)container != control)
{
container.ActiveControl = control;
}
- if (control.IsHandleCreated) {
+ else if (control.IsHandleCreated) {
XplatUI.SetFocus(control.window.Handle);
}
return true;
@@ -4117,8 +4117,8 @@
container = GetContainerControl();
if (container != null && (Control)container != this)
- if (!this.Parent.ContainerSelected)
- container.ActiveControl = this;
+ if (!this.Parent.ContainerSelected)
+ container.ActiveControl = this;
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs
2007-01-10 19:27:11 UTC (rev 70803)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs
2007-01-10 19:28:52 UTC (rev 70804)
@@ -1520,9 +1520,6 @@
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnActivated(EventArgs e)
{
- if (is_loaded)
- SelectActiveControl ();
-
EventHandler eh = (EventHandler)(Events
[ActivatedEvent]);
if (eh != null)
eh (this, e);
@@ -1553,8 +1550,6 @@
OnLoad(EventArgs.Empty);
- SelectActiveControl ();
-
// Send initial location
OnLocationChanged(EventArgs.Empty);
@@ -1934,6 +1929,9 @@
case Msg.WM_ACTIVATE: {
if (m.WParam !=
(IntPtr)WindowActiveFlags.WA_INACTIVE) {
+ if (is_loaded)
+ SelectActiveControl ();
+
OnActivated(EventArgs.Empty);
} else {
OnDeactivate(EventArgs.Empty);
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches