Search code examples
c#wpfuwpxaml-islands

How to propagate Home/End button press to a UWP RichEditBox inside of a WPF ScrollViewer?


In a WPF application (targeting .NET core 3.1) on one of the windows, I have a ScrollViewer and inside the ScrollViewer (among other elements) I placed a custom UWP control, which contains a RichEditBox. I added this custom UWP control via XamlHosts:

<Window xmlns:xaml="clr-namespace:Microsoft.Toolkit.Wpf.UI.XamlHost;assembly=Microsoft.Toolkit.Wpf.UI.XamlHost">
    ...
     <ScrollViewer>
        <Grid>
            ...
            <xaml:WindowsXamlHost InitialTypeName="UWPControls.MyRichBox" x:Name="UwpRichEditBox"/>
        </Grid>
    </ScrollViewer>
<Window>

The UWP styled RichEditBox shows up in the WPF app, I can type text, move the caret with the arrow buttons, but some of the key events are not working. For example I can't use the Home/End buttons to go to the beginning or to the ending of a line in the RichEditBox.

The issue is that, the ScrollViewer in the WPF app catches these button presses (Home/End/Ctrl+Right-Left) and it's not propagated towards the Xaml Island RichEditBox control. I know this, because if I remove the ScrollViewer, the issue disappears.

I tried to set Focusable="False" and IsTabStop="False" for the ScrollViewer, but didn't help. I can catch these keyboard events in WPF, but in the XamlIsland UWP control the events are not fired at all when I press the Home or End buttons (nor the KeyDownEvent, neither the PreviewKeyDownEvent). For other keys they are fired.

Can I somehow prevent the ScrollViewer to catch keyboard events? Or can I somehow raise a keyboard event on a UWP RichEditBox when I catch them in WPF?


Solution

  • Finally I could solve this issue, by sub-classing the ScrollViewer and overriding the OnKeyDown method.

    namespace MyNameSpace.Custom {
        public class MyScrollViewer : ScrollViewer {
            protected override void OnKeyDown(KeyEventArgs e) {
                // do nothing!
            }
        }
    }
    

    Then use this control in XAML view

    <Window x:Class="..."
            xmlns:custom="clr-namespace:MyNameSpace.Custom">
        <custom:MyScrollViewer>
            ....
        </custom:MyScrollViewer>
    </Window>