icsharpcode / AvalonEdit

The WPF-based text editor component used in SharpDevelop
http://avalonedit.net/
MIT License
1.86k stars 470 forks source link

Focus of Text Edit causes Scroll Viewer to Jump When Used Inside Container Panel #396

Closed chaojian-zhang closed 1 year ago

chaojian-zhang commented 1 year ago

Scenario: When using TextEdit inside a large page which already has a scroll viewer, and when the overall height of the TextEdit exceeds visible area, when LMB mouse click on the TextEdit and causing it to has focus, the TextEdit control will force the containing scroll viewer to jump and select (unexpectedly) a range of text.

Expectation: Don't jump, don't do anything to the containing scrollviewer. For instance, when using regular TextBox, there is no such issue.

Demonstration:

https://user-images.githubusercontent.com/7077098/228344050-27272fd8-fc2d-4a08-94e1-540ec5e9b1c7.mp4

The TextEdit control forces the scroll viewer to scroll and cause itself to select a range of text when gaining focus!

Source:

<Window x:Class="WpfApp2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp2"
        xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
        <StackPanel>
            <Label Content="Test"/>
            <Label Content="Test"/>
            <Label Content="Test"/>
            <avalonEdit:TextEditor 
                Text="Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;"
                MaxHeight="600" WordWrap="True" VerticalScrollBarVisibility="Visible"
                                   ShowLineNumbers="True">
            </avalonEdit:TextEditor>
            <Label Content="Test"/>
            <Label Content="Test"/>
            <Label Content="Test"/>
            <Label Content="Test"/>
            <Label Content="Test"/>
            <Label Content="Test"/>
            <Label Content="Test"/>
        </StackPanel>
    </ScrollViewer>
</Window>

Expected behavior:

https://user-images.githubusercontent.com/7077098/228344459-e2f10bca-bb5b-4a03-bc76-ffcfd2316954.mp4

When using old good text box, there is no such issue!

Source:

<Window x:Class="WpfApp2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp2"
        xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
        <StackPanel>
            <Label Content="Test"/>
            <Label Content="Test"/>
            <Label Content="Test"/>
            <TextBox
                Text="Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;Text&#xA;"
                MaxHeight="600" TextWrapping="WrapWithOverflow" VerticalScrollBarVisibility="Visible">
            </TextBox>
            <Label Content="Test"/>
            <Label Content="Test"/>
            <Label Content="Test"/>
            <Label Content="Test"/>
            <Label Content="Test"/>
            <Label Content="Test"/>
            <Label Content="Test"/>
        </StackPanel>
    </ScrollViewer>
</Window>
jimfoye commented 1 year ago

The problem is that the outer ScrollViewer is trying to scroll the editor into view. Meanwhile, AvalonEdit has detected the mouse being clicked and is trying to figure out if it needs to start or extend a selection. The editor actually gets scrolled (thus, the jumpiness), and then AvalonEdit does set a selection.

Someone else having the same problem (but not with AvalonEdit):

https://stackoverflow.com/questions/20842630/wpf-stackpanel-jumps

That article suggests handling the RequestBringIntoView and setting e.Handled to true. I tried this (on either the TextEditor or TextArea) and it seemed to work.

Just as with your other report - I'm not sure why TextBox doesn't have this problem, I looked at the source code and didn't see a handler for RequestBringIntoView, but that might take a lot of time to figure out.

chaojian-zhang commented 1 year ago

Thanks for the reply!

I have tried your solution and it works.

jimfoye commented 1 year ago

You can close this issue, yes?