Databind the Source Property of the Webbrowser in Wpf

databind the Source property of the WebBrowser in WPF

The problem is that WebBrowser.Source is not a DependencyProperty. One workaround would be to use some AttachedProperty magic to enable this ability.

public static class WebBrowserUtility
{
public static readonly DependencyProperty BindableSourceProperty =
DependencyProperty.RegisterAttached("BindableSource", typeof(string), typeof(WebBrowserUtility), new UIPropertyMetadata(null, BindableSourcePropertyChanged));

public static string GetBindableSource(DependencyObject obj)
{
return (string) obj.GetValue(BindableSourceProperty);
}

public static void SetBindableSource(DependencyObject obj, string value)
{
obj.SetValue(BindableSourceProperty, value);
}

public static void BindableSourcePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
WebBrowser browser = o as WebBrowser;
if (browser != null)
{
string uri = e.NewValue as string;
browser.Source = !String.IsNullOrEmpty(uri) ? new Uri(uri) : null;
}
}

}

Then in your xaml do:

<WebBrowser ns:WebBrowserUtility.BindableSource="{Binding WebAddress}"/>

WebBrowser in WPF with bound Source attached property navigates only once

I just decided to create a new browser in a static border each time I need to navigate.

<Border Grid.Row="1" at:AttachedUri.AttachedUri="{Binding BrowserUri}"/>

And code:

public static void AttachedUriPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
Border border = o as Border;
if (border != null)
{
string uri = e.NewValue as string;
if (!String.IsNullOrEmpty(uri))
{
Uri link = new Uri(uri);
WebBrowser newBrowser = new WebBrowser();
newBrowser.Navigate(link);
border.Child = newBrowser;
}
}
}

Can I bind HTML to a WPF Web Browser Control?

See this question.

To summarize, first you create an Attached Property for WebBrowser

public class BrowserBehavior
{
public static readonly DependencyProperty HtmlProperty = DependencyProperty.RegisterAttached(
"Html",
typeof(string),
typeof(BrowserBehavior),
new FrameworkPropertyMetadata(OnHtmlChanged));

[AttachedPropertyBrowsableForType(typeof(WebBrowser))]
public static string GetHtml(WebBrowser d)
{
return (string)d.GetValue(HtmlProperty);
}

public static void SetHtml(WebBrowser d, string value)
{
d.SetValue(HtmlProperty, value);
}

static void OnHtmlChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
WebBrowser webBrowser = dependencyObject as WebBrowser;
if (webBrowser != null)
webBrowser.NavigateToString(e.NewValue as string ?? " ");
}
}

And then you can Bind to your html string and NavigateToString will be called everytime your html string changes

<WebBrowser local:BrowserBehavior.Html="{Binding MyHtmlString}" />

Is there an MVVM-friendly way to use the WebBrowser control in WPF?

I used this in my bindable webbrowser wrapper:

    CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseBack, BrowseBack, CanBrowseBack));
CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseForward, BrowseForward, CanBrowseForward));
CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseHome, GoHome, TrueCanExecute));
CommandBindings.Add(new CommandBinding(NavigationCommands.Refresh, Refresh, TrueCanExecute));
CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseStop, Stop, TrueCanExecute));

Note that I created my bindable webbrowser as FrameworkElement that exposes DependencyProperties and calls methods on the actual browser element, so i can set CommandBindings on it.

That way, you can use the default NavigationCommands in your View.
The used handlers are:

private void CanBrowseBack(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = webBrowser.CanGoBack;
}

private void BrowseBack(object sender, ExecutedRoutedEventArgs e) {
webBrowser.GoBack();
}

private void CanBrowseForward(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = webBrowser.CanGoForward;
}

private void BrowseForward(object sender, ExecutedRoutedEventArgs e) {
webBrowser.GoForward();
}

private void TrueCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; }

private void Refresh(object sender, ExecutedRoutedEventArgs e) {
try { webBrowser.Refresh(); }
catch (Exception ex) { PmsLog.LogException(ex, true); }
}

private void Stop(object sender, ExecutedRoutedEventArgs e) {
mshtml.IHTMLDocument2 doc = WebBrowser.Document as mshtml.IHTMLDocument2;
if (doc != null)
doc.execCommand("Stop", true, null);
}
private void GoHome(object sender, ExecutedRoutedEventArgs e) {
Source = new Uri(Home);
}


Related Topics



Leave a reply



Submit