Firas Msw
Firas Msw

Reputation: 27

Replacement of WinForm WebBrower in Wpf

I'm trying to use function from winform Project to my WPF Project, but the code seems not work with WPF or the structure of WPF. After many hours research I figured out that this code only work for winfowm. I really need to use it to print to thermal printer and I'm using to print html because my printer in this case will print Arabic characters.

Here is the code:

private void button2_Click(object sender, EventArgs e)
{    
    StartBrowser(xx); 
}

public static void StartBrowser(string source)
{
    var th = new Thread(() =>
    {
        var webBrowser = new WebBrowser();
        webBrowser.ScrollBarsEnabled = false;
        webBrowser.IsWebBrowserContextMenuEnabled = true;
        webBrowser.AllowNavigation = true;
        webBrowser.DocumentCompleted += webBrowser_DocumentCompleted1;
        webBrowser.DocumentText = source;

        Application.Run();
    });
    th.SetApartmentState(ApartmentState.STA);
    th.Start();
}
static void webBrowser_DocumentCompleted1(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    var webBrowser = (WebBrowser)sender;
    webBrowser.SetBounds(0, 0, 0, 0);       
    webBrowser.Print();        
}

Is there any other way to print HTML like this using WPF?

Upvotes: 1

Views: 315

Answers (2)

haldo
haldo

Reputation: 16701

You could do something similar using WebView2. However, this method doesn't replicate the current behaviour exactly. The WebView2 control needs to be added to the UI before it will be fully initialized.

Follow the steps in Get started with WebView2 in WPF apps:

  1. Make sure you have the WebView2 runtime installed
  2. Add the WebView2 control to your window/page/control:
    <DockPanel>
        <DockPanel DockPanel.Dock="Top">
            <Button x:Name="PopulateWebView2" 
                    Click="PopulateWebView2_Click" 
                    Content="Print"/>
        </DockPanel>
        <wv2:WebView2 Name="webView2" />
    </DockPanel>
    
  3. Initialize WebView2, and call this in the window/page constructor:
    void InitializeAsync()
    {
        webView2.EnsureCoreWebView2Async(null);
    }
    
  4. Handle the button click and print the page.
    private void PopulateWebView2_Click(object sender, RoutedEventArgs e)
    {
        webView2.NavigateToString(xx); // your html string to populate the browser
        webView2.NavigationCompleted += async (s, e) =>
        {
            await webView2.CoreWebView2.PrintToPdfAsync(@"Path/To/file.pdf");
        };
    }
    

As mentioned, the WebView2 control needs to be rendered on the UI before it can be fully initialized. This will print the page as a PDF file to the path specified in PrintToPdfAsync(path).

You could use the built-in print dialog and use the DOM to execute a print command instead using the following command, however that will require input from the user to select the file location:

await webView2.CoreWebView2.ExecuteScriptAsync("window.print();")

Upvotes: 2

rfmodulator
rfmodulator

Reputation: 3738

It will work as written in WPF, as well as it does in WinForms anyway...

First, add a reference to the System.Windows.Forms assembly.

Then qualify everything...

using WinForms = System.Windows.Forms;

public static void StartBrowser(string source)
{
    var th = new Thread(() =>
    {
        var webBrowser = new WinForms.WebBrowser();
        webBrowser.ScrollBarsEnabled = false;
        webBrowser.IsWebBrowserContextMenuEnabled = true;
        webBrowser.AllowNavigation = true;
        webBrowser.DocumentCompleted += webBrowser_DocumentCompleted1;
        webBrowser.DocumentText = source;

        WinForms.Application.Run();
    });
    th.SetApartmentState(ApartmentState.STA);
    th.Start();
}

static void webBrowser_DocumentCompleted1(object sender, WinForms.WebBrowserDocumentCompletedEventArgs e)
{
    var webBrowser = (WinForms.WebBrowser)sender;
    webBrowser.SetBounds(0, 0, 0, 0);
    webBrowser.Print();

}

Upvotes: 1

Related Questions