Search code examples
wpftextboxmouseeventcoordinatesmouse-position

How to get TextBox's line from mouse position?


I have a TextBox which has many lines of text, it's being update like this:

  public void UpdateMessageBox(TextBox textBox, string text)
    {
        textBox.SelectionStart = 0;
        textBox.SelectionLength = 0;
        textBox.SelectedText = String.Format("{0:HH:mm:ss }", DateTime.Now) + text + "\n";
        textBox.ScrollToHome();
    }

Now I need to get a text from a line on which mouse middle button was clicked right away, not by selecting line via left click first.

   private void textBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        if (e.ChangedButton == MouseButton.Middle && e.ButtonState == MouseButtonState.Pressed)
        {
            e.MouseDevice.GetPosition(textBox) //what next?
        }
    }

How can I get textBox line and it's text from mouse position?


Solution

  • XAML

    <Grid x:Name="LayoutRoot">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <TextBox Width="300"
                Height="200"
                PreviewMouseDown="TextBox_PreviewMouseDown"
                Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut consectetur iaculis enim sed condimentum. Nunc vestibulum fermentum fermentum. Nam arcu ipsum, vestibulum eu felis a, varius gravida dolor. Pellentesque tempor cursus quam, mattis volutpat odio eleifend cursus. Morbi placerat auctor aliquam. Aliquam erat volutpat. Curabitur dictum convallis nibh in ullamcorper. "
                TextWrapping="Wrap" />
        <TextBlock x:Name="myTextBlock"
                Grid.Row="1"
                HorizontalAlignment="Center" />
    </Grid>
    

    Codebehind

    private void TextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        if (e.ChangedButton == MouseButton.Middle)
        {
            var myTextBox = (TextBox)sender;
    
            var myCharIndex = myTextBox.GetCharacterIndexFromPoint(Mouse.GetPosition(myTextBox), true);
            var myLineIndex = myTextBox.GetLineIndexFromCharacterIndex(myCharIndex);
    
            var myLine = myTextBox.GetLineText(myLineIndex);
    
            myTextBlock.Text = myLine;
        }
    }