1

I'm designing an article editor for my company and I'd like to be able to show a live preview of the article in a separate WebBrowser window/control. The WebBrowser control needs to refresh the page every time the user changes anything in one of the fields for the article.

Previously, I had the WebBrowser control on the same form, but for space reasons, I had to break it out onto a separate form and access it using a button on the editor form. However, since I moved that control into a separate form, the WebBrowser gains focus on every refresh, meaning I can type one character and then I have to click back to the textbox I was typing in.

My question: Is there a way to refresh that preview page in the background without it stealing the focus so that I can update the preview to reflect what the user is typing without interrupting the user while typing?

Here are the methods for showing and refreshing the preview, respectively:

private void buttonShowPreview_Click(object sender, EventArgs e)
    {
        if (buttonShowPreview.Tag == null)
        {
            Form browserForm = new Form();
            browserForm.FormClosing += new FormClosingEventHandler(delegate(Object form, FormClosingEventArgs args)
            {
                if (args.CloseReason == CloseReason.UserClosing)
                {
                    args.Cancel = true;
                    browserForm.Hide();
                    previewShowing = false;
                }
            });

            browserForm.Size = new System.Drawing.Size(1024, 768);
            browserForm.DesktopLocation = new System.Drawing.Point(0, 0);

            browserForm.Text = "Article Preview";

            preview = new WebBrowser();
            browserForm.Controls.Add(preview);
            preview.Dock = DockStyle.Fill;
            preview.Navigate("about:blank");

            buttonShowPreview.Tag = browserForm;
        }

        Form previewForm = buttonShowPreview.Tag as Form;

        previewForm.Show();
        previewShowing = true;
        RefreshPreview();
    }

private void RefreshPreview(string jumpToAnchor)
    {
        if (preview != null)
        {
            preview.Document.OpenNew(true);
            preview.Document.Write(structuredContent.GetStructuredContentHTML(content, jumpToAnchor, false));
            preview.Refresh(); 
        }
    }
dbooher
  • 87
  • 2
  • 9
  • Declare the browser form as a variable of you editor form and don't recreate the form at each click. and call previewForm.show only at first click. Call the preview refresh in a timer (e.g. every 2 seconds), if you detect some changes in the edited text since last refresh.. – Graffito Jul 02 '15 at 15:00
  • I only create the form on the first click and then save it as the tag for the preview button. I call previewForm.show on every click of the button because I want the user to be able to close the preview window and reopen it if they want. I wanted it to be more responsive than every two seconds, but if that's the only way to do it, so be it – dbooher Jul 02 '15 at 15:14

1 Answers1

1

Based on the answer by Robberechts here, try disabling the parent Form, updating your WebBrowser, then re-enabling the parent Form again in the DocumentCompleted() event:

    private void buttonShowPreview_Click(object sender, EventArgs e)
    {
        if (buttonShowPreview.Tag == null)
        {
            Form browserForm = new Form();
            browserForm.FormClosing += new FormClosingEventHandler(delegate(Object form, FormClosingEventArgs args)
            {
                if (args.CloseReason == CloseReason.UserClosing)
                {
                    args.Cancel = true;
                    browserForm.Hide();
                }
            });

            preview = new WebBrowser();

            preview.DocumentCompleted += preview_DocumentCompleted; // handle the DocumentCompleted() event

            browserForm.Controls.Add(preview);
            preview.Dock = DockStyle.Fill;
            preview.Navigate("about:blank");

            buttonShowPreview.Tag = browserForm;
        }

        Form previewForm = buttonShowPreview.Tag as Form;

        previewForm.Size = new System.Drawing.Size(1024, 768);
        previewForm.DesktopLocation = new System.Drawing.Point(0, 0);

        previewForm.Text = "Article Preview";

        RefreshPreview();
        previewForm.Show();
    }

    private void RefreshPreview(string jumpToAnchor)
    {
        if (preview != null && preview.Parent != null)
        {
            preview.Parent.Enabled = false; // disable parent form

            preview.Document.OpenNew(true);
            preview.Document.Write(structuredContent.GetStructuredContentHTML(content, jumpToAnchor, false));
            preview.Refresh();
        }
    }

    private void preview_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        WebBrowser wb = sender as WebBrowser;
        if (wb.Parent != null)
        {
            wb.Parent.Enabled = true; // re-enable parent form
        }
    }
Community
  • 1
  • 1
Idle_Mind
  • 38,363
  • 3
  • 29
  • 40
  • 1
    That's done it. It's a little slow, but it's exactly what I wanted, so I'll just have to try to optimize it – dbooher Jul 02 '15 at 15:26