Kente
Kente

Reputation: 83

Global event handler for TextBox getting focus by mouse click

I have a situation when I want to detect when a TextBox, anywhere in the application, has been brought into focus by the user clicking on it with the mouse, or touch. I have "solved" this by adding a global event handler like this:

Application.Current.MainWindow.AddHandler(UIElement.MouseLeftButtonUpEvent, new MouseButtonEventHandler(txt_MouseLeftButtonUp), true);

...

void txt_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
  if (e.OriginalSource is TextBox)
  {
    // Do somthing
  }
}

However, if the user clicks the edges of a textbox instead of in the middle, quite often an hosting control (Grid, Border etc.) receives the mouse event and somehow passes this on to the contained TextBox, that will handle it and receive focus. This makes the approach above fruitless as the TextBox will not be the e.OriginalSource in this case and I have found no way of identifying that a TextBox was brought into focus by click.

Deriving TextBox and overriding OnMouseDown for instance, will catch this event and I guess this path could be explored to find a solution to the problem but that would require me to use a custom TextBox everywhere.

Anyone out there with a nice solution for this?

This is an example that will trigger the problem. By clicking the edges of the TextBoxes, the grid will handle the mouse event and focus will be passed on to the TextBox.

<Grid>
    <Grid HorizontalAlignment="Center"
          VerticalAlignment="Center"
          Background="Red">
      <TextBox>2323</TextBox>
    </Grid>

    <Grid Margin="200,0,0,0"
          HorizontalAlignment="Center"
          VerticalAlignment="Center"
          Background="Red" Focusable="False">
      <TextBox>2323</TextBox>
    </Grid>
   </Grid>

Upvotes: 0

Views: 1840

Answers (2)

Steven Rands
Steven Rands

Reputation: 5421

The GotMouseCapture event seems to work:

AddHandler(UIElement.GotMouseCaptureEvent,
    new MouseEventHandler(OnGotMouseCapture), true);

...

void OnGotMouseCapture(object sender, MouseEventArgs e)
{
    if (e.OriginalSource is TextBox)
    {
        // ...
    }
}

When I click on TextBox elements with the mouse this event handler is fired, however focus changes made via keyboard do not fire the event.

Upvotes: 1

DrKoch
DrKoch

Reputation: 9772

Simply handle the GotFocus event for each TextBox.

Upvotes: 0

Related Questions