sansa
sansa

Reputation: 434

manipulate selected text on wpf webbrowser

I'm creating a epub books reader. After displaying the book i want to allow users to add some annotation to the book.

To display the book, I'm using a wpf webbrowser control that loads local html files

I want to manipulate selected text on this control by creating a context menu or showing a popup

i've tried to change the control's contextmenu but by searching i found that isn't possible

this is an example of what i want to do with selected text:

IHTMLDocument2 htmlDocument = (IHTMLDocument2)webBrowser1.Document;

            IHTMLSelectionObject currentSelection = htmlDocument.selection;

            if (currentSelection != null)
            {
                IHTMLTxtRange range = currentSelection.createRange() as IHTMLTxtRange;

                if (range != null)
                {
                    MessageBox.Show(range.text);
                }
            }

Upvotes: 0

Views: 2358

Answers (2)

Devdude
Devdude

Reputation: 99

using mshtml;

private mshtml.HTMLDocumentEvents2_Event documentEvents;

in constructor or xaml set your LoadComplete event:

webBrowser.LoadCompleted += webBrowser_LoadCompleted;

then in that method create your new webbrowser document object and view the available properties and create new events as follows:

private void webBrowser_LoadCompleted(object sender, NavigationEventArgs e)
{
    documentEvents = (HTMLDocumentEvents2_Event)webBrowserChat.Document; // this will access the events properties as needed
    documentEvents.oncontextmenu += webBrowserChat_ContextMenuOpening;
}

private bool webBrowserChat_ContextMenuOpening(IHTMLEventObj pEvtObj)
{
    return false; // ContextMenu wont open
    // return true;  ContextMenu will open
    // Here you can create your custom contextmenu or whatever you want
}

Upvotes: 0

Timothy Groote
Timothy Groote

Reputation: 8643

WPF's native browser control will not let you set a custom context menu.

It gets even worse ; while your mouse is over the browser component, or if it has focus, it will not catch events generated by your input either.

A way around this, is to use the windows forms browser control inside a WindowsFormsHost.

To start, add Windows.Forms to your project references.

Then, do something like the following:

XAML:

<Window x:Class="blarb.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <WindowsFormsHost Name="windowsFormsHost" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
    </Grid>
</Window>

C# code:

public partial class MainWindow : Window
{
    private System.Windows.Forms.WebBrowser Browser;

    public MainWindow()
    {
        InitializeComponent();

        //initialise the windows.forms browser component
        Browser = new System.Windows.Forms.WebBrowser
        {
            //disable the default context menu
            IsWebBrowserContextMenuEnabled = false
        };

        //make a custom context menu with items
        System.Windows.Forms.ContextMenu BrowserContextMenu = new System.Windows.Forms.ContextMenu();
        System.Windows.Forms.MenuItem MenuItem = new System.Windows.Forms.MenuItem {Text = "Take Action"};
        MenuItem.Click += MenuItemOnClick;
        BrowserContextMenu.MenuItems.Add(MenuItem);
        Browser.ContextMenu = BrowserContextMenu;

        //put the browser control in the windows forms host
        windowsFormsHost.Child = Browser;

        //navigate the browser like this:
        Browser.Navigate("http://www.google.com");

    }

    private void MenuItemOnClick(object sender, EventArgs eventArgs)
    {
        //will be called when you click the context menu item
    }
}

This does not yet explain how to do your highlighting though.

You could listen for the event fired by the browser component when it is done loading, and then replace portions of the document it loaded, injecting html code to do the highlighting.

Keep in mind that that might be tricky in some situations (when selecting text across divs, spans or paragraphs for example)

Upvotes: 1

Related Questions