Embed Firefox/Gecko in WPF/C# - c#

I want to embed the current Gecko in my WPF-Project.
I know there is the possibility with the Winforms-Host and the Skybound-Gecko-Library.
But I do not use the standard wpf-theme for my application. It is another and the scrollbar of the control will not be styled. Furthermore, this is an old library which is designed for Firefox 3.
Which is the best library/strategy to use the current Gecko in WPF?

You should have a look at these options, they all use Chromium:
paid: (Awesomium-based)
http://awesomium.com/ (is free for startups)
http://wpfchromium4.codeplex.com/ (uses awesomium)
free: (Chrome Embedded Framework-based)
https://github.com/chillitom/CefSharp (provides WinForms and WPF, but uses CEF1)
https://bitbucket.org/xilium/xilium.cefglue/wiki/Home (uses CEF3, and therefore supports Chrome's multi-process model, flash plugin, and WebGL)

You can probably use WindowsFormsHost, tutorial here
https://nhabuiduc.wordpress.com/2014/09/18/geckofx-net-webbrowser-setup-and-features/
the interesting part is
WindowsFormsHost host = new WindowsFormsHost();
GeckoWebBrowser browser = new GeckoWebBrowser();
host.Child = browser;
gridWeb.Children.Add(host);

WebKit.Net is free: http://sourceforge.net/projects/webkitdotnet/
Their GitHub page seems to have been more recently updated: https://github.com/webkitdotnet

Here is my answer. As stated by Roman, Gecko is Winforms-based, not WPF-based and so has to be incorporated via the WindowsFormsHost.
After creating the Visual Studio project, install the Gecko package via NuGet, using the command: Install-Package Geckofx45
Make sure the WindowsFormsIntegration and System.Windows.Forms references have been added to your project.
In your Configuration Manager, set your configuration to 32-bit, to get rid of the compiler warnings.
Update MainWindow.xaml 'Grid' element to give it a name and the handler for the 'Loaded' event
<Grid
Name="GridWeb"
Loaded="Window_Loaded">
</Grid>
Modify MainWindow.xaml.cs to incorporate the Gecko as well as make it navigate to a page on loading:
public MainWindow()
{
InitializeComponent();
Gecko.Xpcom.Initialize("Firefox");
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
WindowsFormsHost host = new WindowsFormsHost();
GeckoWebBrowser browser = new GeckoWebBrowser();
host.Child = browser;
GridWeb.Children.Add(host);
browser.Navigate("http://www.google.com");
}
I struggle using the SO code editor, so for more detailed explanations and screenshots, see this blog page.

This is an old question, but I came up with a pseudo-solution to add GeckoFX as a XAML tag such as:
<local:GeckoBrowser Width="400" Height="250" />
This can be accomplished by simply wrapping the whole thing in a UserControl such as:
XAML:
<UserControl x:Class="WpfApp1.Browser"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Border x:Name="border" Background="Black" Margin="0"></Border>
</UserControl>
C#:
public partial class Browser : UserControl
{
WindowsFormsHost host = new WindowsFormsHost();
GeckoWebBrowser browser = new GeckoWebBrowser();
public Browser()
{
InitializeComponent();
Xpcom.Initialize("Firefox");
browser.Navigate("http://www.google.com");
host.Child = browser;
border.Child = host;
}
}
Now, you can use the tag in WPF, in the same project where the UserControl exists.
I have been trying to get this to work as a Control in a library, so I can easily port it to any other project/solution, but it keeps giving me an error about mozglue.dll missing. I suspect this is due to the Xpcom.Initialize("Firefox") but I need to investigate further.

Related

Navigating to a url using a winforms webbrowser in a wpf application

I'm building a WPF application which contains a WebBrowser. I would like to use the Document.GetElementByID method with the webbrowser, and my understanding is that the easiest way to do this in WPF is to use the winforms webbrowser and WindowsFormsIntegration (If there's a better way please let me know)
I'm having a problem navigating to the URL. Running the program in debug mode does not throw any errors, and stepping over the navigate code still leaves my webbrowser with the following properties:
wb1.ReadyState = Uninitialized
wb1.Url = null
Am I missing something for navigating to the url? Can I use the Document.GetElementById methods in a WPF webbrowser?
xaml:
<Window x:Class="my program's main window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
...
<WindowsFormsHost Name="wfh">
<WindowsFormsHost.Child>
<wf:WebBrowser/>
</WindowsFormsHost.Child>
</WindowsFormsHost>
Code:
var wb1 = wfh.Child as System.Windows.Forms.WebBrowser;
wb1.Navigate("my url here");
while (wb1.ReadyState != System.Windows.Forms.WebBrowserReadyState.Complete)
{
// this loop never ends because neither readystate nor wb1.Url ever change
}
Add a reference to Microsoft.mshtml (from Assembies > Extensions) to your project. Then use the WPF WebBrowser control and cast its Document property to HTMLDocument:
<WebBrowser x:Name="webBrowser" Navigated="WebBrowserNavigated" />
Code behind:
using mshtml;
...
webBrowser.Navigate("...");
...
private void WebBrowserNavigated(object sender, NavigationEventArgs e)
{
var document = webBrowser.Document as HTMLDocument;
...
}

Is it possible to show SilverLight busy indicator inside Winforms application?

Currently i am using a simple PictureBox with GIF file inside and wonder if this is possible and if it does what the differences between this 2 options
This is what i have at this moment using PictureBox:
pictureBox1.BringToFront();
pictureBox1.Dock = DockStyle.None;
pictureBox1.Visible = true;
You can try hosting SilverLight inside Winforms.
While SilverLight is intended to be used in a web browser, WPF is more native to desktop, and WPF does have a simimar BusyIndicator, it is downloadable from CodePlex-Extended WPF Toolkit.
First define a WPF user control MyBusyIndicator.
<UserControl x:Class="Stackoverflow.MyBusyIndicator"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:xctk="clr-namespace:Xceed.Wpf.Toolkit;assembly=Xceed.Wpf.Toolkit"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<xctk:BusyIndicator IsBusy="True" />
</Grid>
</UserControl>
Then you can host this user control in Winform using an ElementHost, first you add the ElementHost from Form's designer, and in Form's constructor
public partial class MyForm : Form
{
public MyForm ()
{
InitializeComponent();
this.elementHost1.Child = new Stackoverflow.MyBusyIndicator();
}
}
The differences:
While BusyIndicator comes with some properties to let you customize the indicator, it adds a dependency on SL or WPF. With PictureBox all you need to do is preparing animated GIFs. There are many tools for generating animated GIFs.

SharpDx toolkit SwapChainPanel integration

I am currently working with SharpDx for a project that targets Win 8.1 and requires multiple 3D viewports on a page, along with other xaml elements. I have so far been able to install the SharpDx toolkit via Nuget, and been able to run a standard toolkit project. However the project uses the SwapChainBackgroundPanel control as the method of rendering the 3D content, shown below.
MainPage.xaml
<SwapChainBackgroundPanel
x:Class="MyGame1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyGame1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignWidth="1280"
d:DesignHeight="800">
</SwapChainBackgroundPanel>
MainPage.xaml.cs
public sealed partial class MainPage
{
private readonly MyGame1 game;
public MainPage()
{
this.InitializeComponent();
game = new MyGame1();
this.Loaded += (sender, args) => game.Run(this);
}
}
According to documentation I read, the SwapChainBackgroundPanel has been deprecated in favour of the newly introduced SwapChainPanel, however when I attempted to replace the SwapChainBackgroundPanel with the SwapChainPanel, I received an error.
Does anyone know if there is a plan in the immediate future to update the SharpDx toolkit to work with the SwapChainPanel in the same manner as it currently does with the SwapChainBackgroundPanel?
Thanks!
The DirectX 11.2 build already fully supports integration with SwapChainPanel.
I have added a sample that demonstrates this feature.
First, make sure your project references DirectX 11.2 assemblies - this involves project editing, as described here.
After this, edit your page xaml as needed, for example like this (some code is omitted for brevity):
<Page ...>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<SwapChainPanel x:Name="panel" x:FieldModifier="private" />
</Grid>
</Page>
Then you need to run your game as usual like this:
using SharpDX.Toolkit;
public sealed partial class MainPage
{
private readonly Game _game;
public MainPage()
{
InitializeComponent();
_game = new MiniCubeGame();
_game.Run(panel);
}
}
You can move the _game.Run(...) call to Loaded event handler if this fits better your architecture.

How to enable window chrome by using C# code and not XAML?

So I am using the WPFShell to apply chrome to a custom window. I have learned from this article that in order to use it, I have to reference the Microsoft.Windows.Shell library and use this XAML code:
<shell:WindowChrome.WindowChrome>
<shell:WindowChrome
ResizeBorderThickness="6"
CaptionHeight="43"
CornerRadius="25,25,10,10"
GlassFrameThickness="0">
</shell:WindowChrome>
</shell:WindowChrome.WindowChrome>
My question is, how do I enable chrome by using C# code and not XAML? (i.e. How do I apply chrome in code-behind?)
Ah, stupid me. It was easy:
WindowChrome.SetWindowChrome(this, new WindowChrome());
I know that this is a older question, But I noticed that I couldn't get WindowChrome.GetWindowChrome() to work in .NET 4.5. I'm not sure if this has to do with System.Windows.Shell being included within the PresentationFramework assembly. But since it kept returning null there would be no way to update the chrome.
So my solution was to add a 'Name' to the WindowChrome which made it accessible in Code Behind.
XAML:
<Window x:Class="SomeProject.MainWindow"
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"
mc:Ignorable="d"Title="Some Window" WindowStyle="None" ResizeMode="CanResize"
AllowsTransparency="True">
<WindowChrome.WindowChrome>
<WindowChrome x:Name="chrome" ResizeBorderThickness="6" CaptionHeight="0"
GlassFrameThickness="0" CornerRadius="0" UseAeroCaptionButtons="False"/>
</WindowChrome.WindowChrome>
</window>
Code Behind:
using System;
using System.Window;
namespace SomeProject
{
public partial class MainWindow: Window
{
public MainWindow()
{
//Get Existing 'WindowChrome' Properties.
var captionHeight = chrome.CaptionHeight;
//Set Existing 'WindowChrome' Properties.
chrome.GlassFrameThickness = new Thickness(2d);
//Assign a New 'WindowChrome'.
chrome = new System.Windows.Shell.WindowChrome();
}
}
}
I hope this helps someone who needs it.

Active Reports winforms viewer control hosted in WPF Window

There is currently not an available WPF viewer for Active Reports 6. I was attempting to use a host control to display the viewer in a interop host but I'm not having much luck. Has anyone else attempted this successfully? I can't even get the wrapper Viewer control to add to the project toolbox as a custom control at this point. I'm hoping to avoid recreating the wheel.
The existing ActiveReports Viewer works fine in WPF. You can use the below XAML to host it in WPF:
<Window x:Class="ARViewerHostedInWpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:arv="clr-namespace:DataDynamics.ActiveReports.Viewer;assembly=ActiveReports.Viewer6"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Grid>
<WindowsFormsHost Name="windowsFormsHost1">
<arv:Viewer x:Name="ARViewer" Dock="Fill" />
</WindowsFormsHost>
</Grid>
</Window>
The following code in the code-behind of the XAML file will connect a report to the viewer in the XAML above and run it:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
NewActiveReport1 rpt = new NewActiveReport1();
this.ARViewer.Document = rpt.Document;
rpt.Run();
}
}
I'm using the currently available version of ActiveReports 6 to test this.
Hope this helps!
Scott Willeke
GrapeCity

Categories

Resources