是否可以在不失去对文本框的关注的情况下刷新文本更改的单独 WebBrowser 控件?

Is it possible to refresh a separate WebBrowser control on text change without losing focus on textbox?

我正在为我的公司设计文章编辑器,我希望能够在单独的 WebBrowser 中显示文章的实时预览 window/control。每当用户在文章的某个字段中更改任何内容时,WebBrowser 控件都需要刷新页面。

以前,我在同一个窗体上有 WebBrowser 控件,但由于 space 原因,我不得不将它分解到一个单独的窗体中,并使用编辑器窗体上的按钮访问它。但是,由于我将该控件移动到一个单独的表单中,WebBrowser 会在每次刷新时获得焦点,这意味着我可以键入一个字符,然后我必须单击返回到我正在键入的文本框。

我的问题:有没有一种方法可以在后台刷新预览页面而不会窃取焦点,这样我就可以更新预览以反映用户正在输入的内容而无需在打字时打扰用户?

下面分别介绍显示和刷新预览的方法:

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(); 
        }
    }

根据 Robberechts here 的回答,尝试禁用父表单,更新您的 WebBrowser,然后在 DocumentCompleted() 事件中再次重新启用父表单:

    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
        }
    }