2008-11-04 9 views
75

Kann jemand die .Source -Eigenschaft des WebBrowser in WPF (3.5SP1). Ich habe eine Listenansicht, die ich einen kleinen WebBrowser auf der linken Seite und Inhalt auf der rechten Seite haben und die Quelle jedes WebBrowser mit der URI in jedem Objekt gebunden an das Listenelement.Datenbank die Source-Eigenschaft des WebBrowser in WPF

Das habe ich als Proof of Concept bisher, aber die "<WebBrowser Source="{Binding Path=WebAddress}"" kompiliert nicht.

<DataTemplate x:Key="dealerLocatorLayout" DataType="DealerLocatorAddress">     
    <StackPanel Orientation="Horizontal"> 
     <!--Web Control Here--> 
     <WebBrowser Source="{Binding Path=WebAddress}" 
      ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
      ScrollViewer.VerticalScrollBarVisibility="Disabled" 
      Width="300" 
      Height="200" 
      /> 
     <StackPanel Orientation="Vertical"> 
      <StackPanel Orientation="Horizontal"> 
       <Label Content="{Binding Path=CompanyName}" FontWeight="Bold" Foreground="Blue" /> 
       <TextBox Text="{Binding Path=DisplayName}" FontWeight="Bold" /> 
      </StackPanel> 
      <TextBox Text="{Binding Path=Street[0]}" /> 
      <TextBox Text="{Binding Path=Street[1]}" /> 
      <TextBox Text="{Binding Path=PhoneNumber}"/> 
      <TextBox Text="{Binding Path=FaxNumber}"/> 
      <TextBox Text="{Binding Path=Email}"/> 
      <TextBox Text="{Binding Path=WebAddress}"/> 
     </StackPanel> 
    </StackPanel> 
</DataTemplate> 
+0

* Nudge *, um Ihren Beitrag zu beheben. – Donnelle

Antwort

138

Das Problem ist, dass WebBrowser.Source kein DependencyProperty ist. Eine Problemumgehung wäre das Verwenden einiger AttachedProperty-Magie, um diese Fähigkeit zu aktivieren.

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

} 

Dann in XAML zu tun:

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

Erhalte eine Exception für diese "neue Uri (uri)", da die Zeichenfolge "" ist. Vielleicht sollte es .... browser.Source = string.IsNullOrEmpty (uri)? null: neuer Uri (uri); – midspace

+3

Beachten Sie, dass dies nur eine einseitige Bindung ist und die BindableSource-Eigenschaft sich nicht ändert, wenn sich die Webbrowserseite ändert. – Kurren

+0

Sie sind ein Lebensretter. Das hat einwandfrei funktioniert. –

26

ich einen Wrapper Usercontrol schrieb, die Verwendung der DependencyProperties macht:

XAML:

<UserControl x:Class="HtmlBox"> 
    <WebBrowser x:Name="browser" /> 
</UserControl> 

C#:

public static readonly DependencyProperty HtmlTextProperty = DependencyProperty.Register("HtmlText", typeof(string), typeof(HtmlBox)); 

public string HtmlText { 
    get { return (string)GetValue(HtmlTextProperty); } 
    set { SetValue(HtmlTextProperty, value); } 
} 

protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { 
    base.OnPropertyChanged(e); 
    if (e.Property == HtmlTextProperty) { 
     DoBrowse(); 
    } 
} 
private void DoBrowse() { 
    if (!string.IsNullOrEmpty(HtmlText)) { 
     browser.NavigateToString(HtmlText); 
    } 
} 

und es wie so zu verwenden:

<Controls:HtmlBox HtmlText="{Binding MyHtml}" /> 

Das einzige Problem mit diesem ist, dass das WebBrowser-Steuerelement ist nicht „rein“ wpf ... es eigentlich nur ein Wrapper für eine win32-Komponente ist. Dies bedeutet, dass die Steuerung den z-index nicht respektieren, und wird immer ein anderes Element überlagert (zB: in einem Scroll könnte dies einige Probleme verursachen) weitere Informationen über diese win32-wpf Fragen auf MSDN

+0

Dies ist genau das, was ich brauchte, da ich mein eigenes HTML anzeigen möchte. Ordentlich, einfach, und ich verstehe fast, was es tut (-: – Murph

+0

Funktioniert wie ein Champion, danke! –

1

Du wird auch Verwenden Sie eine spezielle separate proxy control. Dies gilt nicht nur für den WebBrowser-Fall, sondern auch für ein solches Steuerelement.

3

Coole Idee Todd.

Ich habe jetzt ähnlich mit dem RichTextBox.Selection.Text in Silverlight 4 gemacht. Danke für Ihren Beitrag. Funktioniert gut.

public class RichTextBoxHelper 
{ 
    public static readonly DependencyProperty BindableSelectionTextProperty = 
     DependencyProperty.RegisterAttached("BindableSelectionText", typeof(string), 
     typeof(RichTextBoxHelper), new PropertyMetadata(null, BindableSelectionTextPropertyChanged)); 

    public static string GetBindableSelectionText(DependencyObject obj) 
    { 
     return (string)obj.GetValue(BindableSelectionTextProperty); 
    } 

    public static void SetBindableSelectionText(DependencyObject obj, string value) 
    { 
     obj.SetValue(BindableSelectionTextProperty, value); 
    } 

    public static void BindableSelectionTextPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) 
    { 
     RichTextBox rtb = o as RichTextBox; 
     if (rtb != null) 
     { 
      string text = e.NewValue as string; 
      if (text != null) 
       rtb.Selection.Text = text; 
     } 
    } 
}  

Hier ist der Xaml-Code.

<RichTextBox IsReadOnly='False' TextWrapping='Wrap' utilities:RichTextBoxHelper.BindableSelectionText="{Binding Content}"/> 
26

Ich habe Todds ausgezeichnete Antwort ein wenig geändert, um eine Version zu produzieren, die mit entweder Strings oder Uris aus der Bindungsquelle meistert:

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

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

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

    public static void BindableSourcePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) 
    { 
     WebBrowser browser = o as WebBrowser; 
     if (browser == null) return; 

     Uri uri = null; 

     if (e.NewValue is string) 
     { 
      var uriString = e.NewValue as string; 
      uri = string.IsNullOrWhiteSpace(uriString) ? null : new Uri(uriString); 
     } 
     else if (e.NewValue is Uri) 
     { 
      uri = e.NewValue as Uri; 
     } 

     browser.Source = uri; 
    } 
-3

Sie müssen es in den ersten Zeilen zu erklären, von die xaml Datei in die Klassendatei, die

xmlns:reportViewer="clr-namespace:CoMS.Modules.Report" 
+2

Dies bietet nicht viel Unterstützung, um das Problem zu lösen. – Woot4Moo

0

Dies ist eine Verfeinerung Todds und Samuels Antwort zu nutzen, einige grundlegenden Logik Räumlichkeiten sowie wir zeigen e der Nullkoaleszenzoperator.

public static void BindableSourcePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) 
{ 
    WebBrowser browser = o as WebBrowser; 

    if ((browser != null) && (e.NewValue != null)) 
     browser.Source = e.NewValue as Uri ?? new Uri((string)e.NewValue); 

} 
  1. Wenn der Browser null ist oder die Lage ist null, können wir nicht auf eine Null Seite verwenden oder navigieren.
  2. Wenn die Elemente in # 1 nicht null sind, dann verwenden Sie sie beim Zuweisen, wenn der neue Wert ein URI ist. Wenn nicht, und der URI ist Null, dann koaleszieren, denn es muss eine Zeichenkette sein, die in einen URI eingefügt werden kann; seit # 1 erzwingt, dass die Zeichenfolge nicht null sein kann.