0x49D1
0x49D1

Reputation: 8704

Show scrollbar in windows phone webbrowser control

I have some content to read, loaded into webbrowser control. I want to see the progress while im reading. Is it possible to show vertical scrolling bar in webbrowser control somehow? Tried ScrollViewer.VerticalScrollVisibility and putting entire webbrowser into ScrollViewer, nothing works!

Upvotes: 0

Views: 1114

Answers (2)

Bajena
Bajena

Reputation: 181

Check out my solution basing on MisterGoodcat's idea. I've created a custom web browser control which injects the javascript after the page is loaded.

XAML:

<UserControl x:Class="Wallet.Views.Controls.WebBrowserWithScrollbar"
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:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Platform"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480">

<Grid>
    <phone:WebBrowser 
            Name="WebBrowserControl"
            IsScriptEnabled="True"
            Margin="0 0 5 0"
            ScriptNotify="WebBrowser_OnScriptNotify">

    </phone:WebBrowser>

    <ScrollBar x:Name="DisplayScrollBar"
                Orientation="Vertical"
                HorizontalAlignment="Right"
                VerticalAlignment="Stretch"
                Minimum="0"
                Maximum="100"
                Value="0" 
                Visibility="Collapsed"/>
</Grid>

Code behind:

/// <summary>
/// Adds a vertical scrollbar to the normal WebBrowser control
/// </summary>
public partial class WebBrowserWithScrollbar : UserControl
{
    #region Dependency Properties
    public static readonly DependencyProperty SourceProperty = DependencyProperty.Register(
        "Source", typeof(string), typeof(WebBrowserWithScrollbar), new PropertyMetadata(string.Empty, OnSourcePropertyChanged));

    #endregion

    #region Fields
    private int _visibleHeight;
    private int _scrollHeight;
    #endregion

    #region Constructors
    public WebBrowserWithScrollbar()
    {
        InitializeComponent();
        this.LoadCompleted += this.WebBrowserControlLoadCompleted;
    }
    #endregion

    #region Event Handlers

    public event LoadCompletedEventHandler LoadCompleted
    {
        add
        {
            WebBrowserControl.LoadCompleted += value;
        }

        remove
        {
            WebBrowserControl.LoadCompleted -= value;
        }
    }

    public event EventHandler<NotifyEventArgs> ScriptNotify
    {
        add
        {
            WebBrowserControl.ScriptNotify += value;
        }

        remove
        {
            WebBrowserControl.ScriptNotify -= value;
        }
    }

    public event EventHandler<NavigationEventArgs> Navigated
    {
        add
        {
            WebBrowserControl.Navigated += value;
        }

        remove
        {
            WebBrowserControl.Navigated -= value;
        }
    }

    public event EventHandler<NavigatingEventArgs> Navigating
    {
        add
        {
            WebBrowserControl.Navigating += value;
        }

        remove
        {
            WebBrowserControl.Navigating -= value;
        }
    }

    public event NavigationFailedEventHandler NavigationFailed
    {
        add
        {
            WebBrowserControl.NavigationFailed += value;
        }

        remove
        {
            WebBrowserControl.NavigationFailed -= value;
        }
    }

    #endregion

    #region Properties
    public string Source
    {
        get
        {
            return (string)this.GetValue(SourceProperty);
        }

        set
        {
            this.SetValue(SourceProperty, value);
        }
    }
    #endregion

    #region Static Methods

    private static void OnSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var controlWrapper = d as WebBrowserWithScrollbar;
        if (controlWrapper != null)
        {
            var webBrowser = controlWrapper.WebBrowserControl;
            var newSource = e.NewValue as string;
            Uri uri;

            if (webBrowser != null &&
                newSource != null &&
                e.NewValue != e.OldValue &&
                !string.IsNullOrEmpty(newSource) &&
                Uri.TryCreate(newSource, UriKind.Absolute, out uri))
            {
                webBrowser.Source = uri;
            }
        }
    }

    #endregion

    #region Methods
    private void WebBrowserControlLoadCompleted(object sender, NavigationEventArgs e)
    {
        this.InitializeScrollBarScript();
    }

    private void WebBrowser_OnScriptNotify(object sender, NotifyEventArgs e)
    {
        var parts = e.Value.Split('=');
        if (parts.Length != 2)
        {
            return;
        }

        int number;
        if (!int.TryParse(parts[1], out number))
        {
            return;
        }

        if (parts[0] == "scrollHeight")
        {
            _scrollHeight = number;
            if (_visibleHeight > 0)
            {
                DisplayScrollBar.Maximum = _scrollHeight - _visibleHeight;
            }
        }
        else if (parts[0] == "clientHeight")
        {
            _visibleHeight = number;
            if (_scrollHeight > 0)
            {
                DisplayScrollBar.Maximum = _scrollHeight - _visibleHeight;
            }
        }
        else if (parts[0] == "scrollTop")
        {
            DisplayScrollBar.Value = number;
        }

        this.DisplayScrollBar.Visibility = this._visibleHeight >= this._scrollHeight ? Visibility.Collapsed : Visibility.Visible;
    }

    private void InitializeScrollBarScript()
    {
        try
        {
            WebBrowserControl.InvokeScript(
                "eval",
                new[]
                    {
                        "function onScroll() { " + "var scrollPosition = document.body.scrollTop;"
                        + "window.external.notify(\"scrollTop=\" + scrollPosition.toString());"
                        + "window.external.notify(\"scrollHeight=\" + document.body.scrollHeight.toString());"
                        + "window.external.notify(\"clientHeight=\" + document.body.clientHeight.toString()); } "

                        + "window.external.notify(\"scrollHeight=\" + document.body.scrollHeight.toString());"
                        + "window.external.notify(\"clientHeight=\" + document.body.clientHeight.toString()); "
                        + "window.onscroll = onScroll"
                    });
        }
        catch (Exception xcp)
        {
            Debug.WriteLine("Exception occured while executing invoke script:");
            Debug.WriteLine(xcp);
            DisplayScrollBar.Visibility = Visibility.Collapsed;
        }
    }
    #endregion
}

Upvotes: 1

0x49D1
0x49D1

Reputation: 8704

..Nobody is answering..
But ive already found the solution. Not quite ideal one and its a bit dirty, but it works and i can show reading progress now. http://www.pitorque.de/MisterGoodcat/post/Somethings-Missing-from-the-WebBrowser-Control.aspx the main idea is to inject some javascript into the page and notify browser about scrolling events; after that change the position of custom scrollbar control placed somewhere near the browser.

Upvotes: 0

Related Questions