Skip to main content
Home Forums Silverlight Programming Report a Silverlight Bug RC0 Error: TextBox is locked and does not fire MouseLeftButtonDown event
12 replies. Latest Post by StefanWick on October 18, 2008.
(0)
sebschmitt
Member
20 points
23 Posts
09-28-2008 5:49 AM |
During my migration to RC0 I discovered a strange new behaviour of the TextBox user control:
Has anybody an idea, why this strange new behaviour occurs and how it might be fixed in other ways than I did?
09-28-2008 9:21 AM |
Update: It seems like the MouseLeftButtonDown event is not fired by the Button user controls either. Maybe all user controls are affected?
Allen Ch...
Star
13662 points
1,780 Posts
09-30-2008 2:22 AM |
Hi,
I cannot reproduce this problem. Could you post a demo project that can reproduce this problem?
stefan.j...
61 points
28 Posts
09-30-2008 7:34 AM |
I can reprocuce the second error:
The MouseLeftButtonDown event doesn't fire, if the TextBox contains Text. Clicking near the TextBox Border (mouse icon: Arrow) works fine. Clicking inside the TextBox (mouse icon has changed) fails.
<UserControl x:Class="TBClickBugRepro.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <TextBox x:Name="Test" Text="123" MouseLeftButtonDown="Test_MouseLeftButtonDown" Height="20" Width="Auto"></TextBox> </Grid></UserControl>
10-01-2008 10:25 AM |
Thanks a lot to Stefan, who already reproduced the second error.However, I was not able to reproduce the first error, since it did not occur in any new Silverlight project I created. The App where it occurs is a bit complex , so it might take some time to find the cause. In the meantime I am happy with my workaround.
The first error however might be severe, if it really affects all Silverlight user controls in RC0.
Is it really an error caused by the release of RC0? If so, will it be fixed?
dbaechtel
59 points
207 Posts
10-01-2008 5:34 PM |
I agree. As long as the cursor is an Insert Cursor (I-beam), the MouseLeftButtonDown or MouseLeftButtonUp events do not fire. If you move to the border of the TextBox where the cursor changes back to the standard selection arrow, the MouseLeftButtonDown event fires and the Sender value sent to the event handler is TextBox. This doesn't seem like it is working properly.
StefanWick
Contributor
2864 points
438 Posts
10-01-2008 7:16 PM |
This is by design and consistent with the behavior in WPF. The TextBox marks the mouse down/up events as handled and thus won't bubble them up any further.
You can get the mouse events by deriving from TextBox like this:
public class TextBox2 : TextBox { protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnMouseLeftButtonDown(e); } protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) { base.OnMouseLeftButtonUp(e); } }
Thanks, Stefan Wick
10-01-2008 8:59 PM |
StefanWick: This is by design and consistent with the behavior in WPF. The TextBox marks the mouse down/up events as handled and thus won't bubble them up any further. Thanks, Stefan Wick
The MouseLeftButtonDown event is raised when the left mouse button is pressed while the mouse pointer is over the UIElement. When the mouse button is released, the MouseLeftButtonUp event is raised. However, if the mouse pointer is moved over another object when the button is released, the UIElement that received theMouseLeftButtonDown event will not receive the MouseLeftButtonUp event. There is no discrete double-click event. A double-click consists of two sequences of MouseLeftButtonDown and MouseLeftButtonUp events.
The MouseLeftButtonDown event is a bubbling event. This means that if multiple MouseLeftButtonDown event handlers are registered for a sequence of objects connected by parent-child relationships in the object tree, the event is received by each object in that relationship. The event is raised by the object that directly receives the input condition that initiates the event, and then bubbles to each successive parent object. The bubbling metaphor indicates that the event starts at the bottom and works its way up the object tree. For a bubbling event, the sender available to the event handler identifies the object where the event is handled, not necessarily the object that actually received the input condition that initiated the event. To get the object that initiated the event, use the Source value of the event's RoutedEventArgs event data.
10-02-2008 1:17 AM |
It actually is consistent. Further down in the reference topic there is an "Important Note" that talks about this.
http://msdn.microsoft.com/en-us/library/system.windows.uielement.mouseleftbuttondown(VS.95).aspx
"Certain control classes (for example Button) provide control-specific handling for mouse events such as MouseLeftButtonDown. The control-specific handling typically involves handling the event at a class level rather than at the instance level, and marking the MouseLeftButtonDown event data's Handled value as true such that the event cannot be handled by instances of the control class, nor by other objects anywhere further along the event route. In the case of Button, the class design does this so that the Click event can be raised instead."
This is exactly what happens here in the TextBox case. The TextBox control marks the events as handled. As I pointed out before, derived classes do receive the events - and they can set the Handled property back to false, then the mouse up/down events will fire on TextBox control. Here is how you do this:
public class TextBox2 : TextBox { protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnMouseLeftButtonDown(e); e.Handled = false; } protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) { base.OnMouseLeftButtonUp(e); e.Handled = false; } }
10-02-2008 1:37 AM |
I disagree that this is consistent. In my opinion it's not consistent when the event is sometimes handled by the control and sometimes not.
I wanted to use this event to clear the Text in a TextBox, when the user clicks inside the Box. Your solution or using the GotFocus event works fine for me.
Thanks,
10-02-2008 1:54 AM |
It is consistent (I assume you are referring to the fact that the Border doesn't handle the events). Here is why:
The Border is a different element in the TextBox's tree. It doesn't take any action when you hit it with a mouse. It does not handle the input, thus it doesn't mark the event as handled, so that others can handle it further up the chain. The input area of the TextBox does take an action when you hit it with a mouse. It does handle the input, thus it marks the event as handled.
Aside from being consistent, this is also compatible with WPF, which has been using the same design and has had the same consistent behavior for years.
mr.saif
417 points
147 Posts
10-18-2008 8:09 AM |
But this breaks things for my project.....:(
10-18-2008 11:16 AM |
Can you explain the scenario that this breaks? Does deriving your own class from TextBox not un-break it for you?