Search code examples
xamluwpwinrt-xaml

Windows UWP ScrollViewer scrollbar overlaps contents


enter image description here

How do you stop a ScrollViewer's scrollbar from overlapping content like this?

I have a RichTextBlock containing text and no matter how wide I make the RichTextBlock, or how I change the Margin and Padding values, I cannot get the scrollbar to move further to the right to stop this overlap from happening. I'm running Windows 10 and it is configured to hide scrollbars until the mouse pointer hovers over them.

Below is the XAML for my app.

<Page
    x:Class="PaulWinPOS1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PaulWinPOS1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid Margin="0,26,0,0">
        <Button x:Name="butConnect" Content="Connect" Margin="0,38,48,0" VerticalAlignment="Top" RenderTransformOrigin="-3.274,0.344" HorizontalAlignment="Right" Height="32" Click="ButConnect_Click" Width="92"/>
        <Button x:Name="butLogin" Content="Login" Margin="0,92,48,0" VerticalAlignment="Top" RenderTransformOrigin="-3.274,0.344" HorizontalAlignment="Right" Height="32" Width="92" IsEnabled="False" Click="ButLogin_Click"/>
        <Button x:Name="butAdd" Content="Add Item" Margin="0,143,48,0" VerticalAlignment="Top" RenderTransformOrigin="-3.274,0.344" HorizontalAlignment="Right" Width="92" IsEnabled="False" Click="ButAdd_Click"/>

        <ScrollViewer x:Name="scrollViewerWeb" 
            HorizontalScrollBarVisibility="Auto"
            VerticalScrollBarVisibility="Auto" 
            HorizontalAlignment="Left"
            Width="350"
            Padding="16,0"
            Grid.RowSpan="10"
            FontFamily="Segoe UI" RequestedTheme="Dark" ZoomMode="Enabled" 
            Margin="669,304,0,0" >
            <WebView x:Name="webviewReceipt" 
                Margin="10,10,50,10"
                HorizontalAlignment="Left" 
                Height="333" Width="300"
                VerticalAlignment="Top"
                ScrollViewer.VerticalScrollMode="Enabled"
                ScrollViewer.VerticalScrollBarVisibility="Visible" />
        </ScrollViewer>
        
        <Button x:Name="butDisconnect" Content="Disconnect" Margin="0,244,48,0" VerticalAlignment="Top" RenderTransformOrigin="-3.274,0.344" HorizontalAlignment="Right" Height="32" Width="92" Click="ButDisconnect_Click"/>


    </Grid>
</Page>

Solution

  • The scroll bar of WebView is special and cannot be solved by the conventional ScrollViewer additional properties, but the scroll bar of the WebView can be disabled through the CSS of the web page.

    body {
       -ms-overflow-style: none;
    }
    

    If you cannot modify the source code of the webpage, you can perform the following operations after the WebView content is loaded:

    private async void webviewReceipt_DOMContentLoaded(WebView sender, WebViewDOMContentLoadedEventArgs args)
    {
        string js = "var style = document.createElement('style');" +
                   "style.type = 'text/css';" +
                   "style.innerHTML = \"body{ -ms-overflow-style: none !important; }\";" +
                   "document.getElementsByTagName('Head').item(0).appendChild(style); ";
        await webviewReceipt.InvokeScriptAsync("eval", new string[] { js });
    }
    

    Update

    If we need to display a scroll bar, we can add a padding-right to the body so that the scroll bar does not block the content.

    private async void webviewReceipt_DOMContentLoaded(WebView sender, WebViewDOMContentLoadedEventArgs args)
    {
        string js = "var style = document.createElement('style');" +
                   "style.type = 'text/css';" +
                   "style.innerHTML = \"body{ padding-right: 24px; }\";" +
                   "document.getElementsByTagName('Head').item(0).appendChild(style); ";
        await webviewReceipt.InvokeScriptAsync("eval", new string[] { js });
    }