Bug or Feature? CancelButton vs Escape Key

G

Guest

I have noiticed a change in behavior between VB6 and VB.Net (2003 and 2005)
that I don't find documented anywhere. It has to do with 'causesvalidation'
and the button on the Form defined to be the cancelbutton. According to the
documentation: "The cancel button for a form is the button control that is
clicked whenever the user presses the ESC key." Yet 'clicking' the button
and pressing the escape key do not produce the same results. Simple example:
One textbox, 1 button, the button is the forms 'cancelbutton', the buttons
'causesvalidation' property is False. The following code:
Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Me.Close()
End Sub

Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As
System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
e.Cancel = False
End Sub

Private Sub TextBox1_Validating(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating
If TextBox1.Text.Length < 5 Then
e.Cancel = True
End If
End Sub
End Class

Clicking the button works, tabing to the button and pressing the spacebar
works, closing the form from the controlbox works .... pressing the escape
button does NOT work! Surprisingly, if I change the TextBox causesvalidation
to False, then the escape key works! This sounds (looks) like a bug to me.
 
J

Jeffrey Tan[MSFT]

Hi Terry,

Thanks for your post!

Based on my understanding, there are a TextBox and a Button on the form,
the Button is set to the CancelButton of Form. TextBox.CancelValidation
property is set to true, while Button.CancelValidation is set to false.
Button.Click event will invoke Me.Close method to close the Form. You find
that pressing ESC key does not close the Form. While after setting
TextBox.CancelValidation property to false, you can use ESC key to close
the Form now. If I have misunderstood you, please feel free to tell me,
thanks.

Yes, I can reproduce this behavior with the above conditions. Actually,
this behavior can only be reproduced when the initial focus is in TextBox,
not Button. If the Button control has a lower TabIndex property value, it
will has the initial focus when Form lauches, then pressing ESC will work
without any problem.

Actually, the logic is that the validating only applies to the
focused/active control on the Form. When the focus is in TextBox and we
press ESC, the CancelButton logic will invoke Button.PerformClick method.
Then the validation code in Button.PerformClick method will check that the
active Control(TextBox in our scenario)'s CancelValidation is true, so it
will run your TextBox1_Validating code, which fails to
validate(TextBox1.Text.Length < 5) and the ESC
operation(Button.PerformClick) is cancelled.

If the focus is on the Button, the Validating code will only check
Button.CancelValidation property, not TextBox.CancelValidation property. So
the ESC operation is not cancelled. So this is not a bug, but by design
behavior.

If you are curious, below is the logic code in Button.PerformClick method:

public void PerformClick()
{
if (base.CanSelect)
{
bool flag1;
bool flag2 = base.ValidateActiveControl(out flag1);
if (!base.ValidationCancelled && (flag2 || flag1))
{
base.ResetFlagsandPaint();
this.OnClick(EventArgs.Empty);
}
}
}
As you can see, Button.PerformClick method invokes ValidateActiveControl()
method to do the validation work.

So in your scenario, the key point to workaround the validation is setting
TextBox.CancelValidation to false, not Button.CancelValidation property.

Hope my analysis makes the problem clear. If you still have anything
unclear, please feel free to tell me, thanks!

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Hi Jeffrey,
Thank you for your response. If I understand you correectly, you are
telling me that this undocumented change from VB6 is by design. That someone
decided that pressing the escape key should behave differently then clicking
the cancel button. Well then, imho that is a design bug! If clicking the
button with the mouse first makes it the active control followed my the click
event then the escape key should also make it the active control before
calling the PerformClick method. The point is, there really should be no
difference between clicking the button and pressing the escape key. The fix
of making the causesvalidation property for the textbox false implies that I
would have to do that for all the textbox controls on a form thereby
eliminating the ability to validate while moving between them. Of course, I
could go back to the way we did this before there was a validating event and
use the lostfocus event together with the focus() method to control it myself
- but wasn't the validating event put there to eliminate the need to do that?
Looks to me like the only true workaround for this is to not define a
cancelbutton and force the user to click it with the mouse.
--
Terry


"Jeffrey Tan[MSFT]" said:
Hi Terry,

Thanks for your post!

Based on my understanding, there are a TextBox and a Button on the form,
the Button is set to the CancelButton of Form. TextBox.CancelValidation
property is set to true, while Button.CancelValidation is set to false.
Button.Click event will invoke Me.Close method to close the Form. You find
that pressing ESC key does not close the Form. While after setting
TextBox.CancelValidation property to false, you can use ESC key to close
the Form now. If I have misunderstood you, please feel free to tell me,
thanks.

Yes, I can reproduce this behavior with the above conditions. Actually,
this behavior can only be reproduced when the initial focus is in TextBox,
not Button. If the Button control has a lower TabIndex property value, it
will has the initial focus when Form lauches, then pressing ESC will work
without any problem.

Actually, the logic is that the validating only applies to the
focused/active control on the Form. When the focus is in TextBox and we
press ESC, the CancelButton logic will invoke Button.PerformClick method.
Then the validation code in Button.PerformClick method will check that the
active Control(TextBox in our scenario)'s CancelValidation is true, so it
will run your TextBox1_Validating code, which fails to
validate(TextBox1.Text.Length < 5) and the ESC
operation(Button.PerformClick) is cancelled.

If the focus is on the Button, the Validating code will only check
Button.CancelValidation property, not TextBox.CancelValidation property. So
the ESC operation is not cancelled. So this is not a bug, but by design
behavior.

If you are curious, below is the logic code in Button.PerformClick method:

public void PerformClick()
{
if (base.CanSelect)
{
bool flag1;
bool flag2 = base.ValidateActiveControl(out flag1);
if (!base.ValidationCancelled && (flag2 || flag1))
{
base.ResetFlagsandPaint();
this.OnClick(EventArgs.Empty);
}
}
}
As you can see, Button.PerformClick method invokes ValidateActiveControl()
method to do the validation work.

So in your scenario, the key point to workaround the validation is setting
TextBox.CancelValidation to false, not Button.CancelValidation property.

Hope my analysis makes the problem clear. If you still have anything
unclear, please feel free to tell me, thanks!

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Terry,

Thanks for your feedback!

Oh, yes, after giving your reply a second read, I think I understand you
much better.

Yes, it seems clicking on the button will not trigger the Validating event
and will close the Form because the Button.CauseValidation is set to false,
while pressing ESC does not close the Form because it triggers the
Validating event. This is really a strange behavior, the ESC key should
have the same behavior as Button.Click.

I will spend some more time in this issue to find out the root cause. I
will get back to you ASAP. Thanks for your understanding.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Terry,

Sorry for let you wait.

Yes, after performing some research, I found that some customers had
reported the similar issue as a bug. The problem lies in that the ESC key
causes the validating from Button.PerformClick method, while clicking
button will trigger the validating through Control.WmSetFocus internal
method. So it seems that Button.PerformClick method does not check
Button.CauseValidation correctly internally.

Please refer to the bug link below for more information:
"CausesValidation has no effect on Button when PerformClick is called. "
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?Feedbac
kID=116242

To workaround this problem, you may intercept the ESC key explicitly and
set AutoValidate property to AutoValidate.Disable to disable the
validating, sample code snippet is listed below:

Protected Overrides Function ProcessDialogKey(ByVal keyData As
System.Windows.Forms.Keys) As Boolean
Dim cancel As Button = CType(Me.CancelButton, Button)
If keyData = Keys.Escape Then
Me.AutoValidate = Windows.Forms.AutoValidate.Disable
cancel.PerformClick()
Me.AutoValidate = Windows.Forms.AutoValidate.Inherit
Return True
End If
Return MyBase.ProcessDialogKey(keyData)
End Function

Thank you for reporting this bug and sorry for introducing any
inconvinience to you.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jeffrey Tan[MSFT]

You are welcome.

Yes, if you meet further bug-like issue, after performing search in google
without any success, it is a good place to perform search in the MSDN
customer feedback center below:
"Visual Studio and .NET Framework Feedback"
http://connect.microsoft.com/feedback/default.aspx?SiteID=210

Some general known issues may have been reported by other customers, and
this site will save you a lot of time.

Anyway, if you can not find anything useful in this site, please feel free
to post in newsgroup, I will try my best to help you :)

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Hi Jeffrey,
Thank you for the link to the feedback site. I went there and searched
for 'escape key' and found the issue - problem is - it says it has been fixed
and the issue is closed. Was there some other place that you meant to direct
me to?
 
J

Jeffrey Tan[MSFT]

Hi Terry,

Thanks for your feedback!

If I did not misunderstand you, you are talking about the bug link below,
yes?
"Escape key doesn't cancel a form when validation is used "
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?Feedbac
kID=116968

Yes, the description of the customer looks like the same with your problem,
however they are not the same one. I have downloaded the customer's problem
in internal bug database and given it a test. The customer did not set
Button.CauseValidation property to false. So this bug link talks about
another issue in VS2005 beta version which is fixed in VS2005 RTM.

The bug link below is the same issue as yours:
"CausesValidation has no effect on Button when PerformClick is called."
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?Feedbac
kID=116242

Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top