2008-11-04 9 views
75

¿Alguien sabe cómo enlazar datos con la propiedad .Source del WebBrowser en WPF (3.5SP1)? Tengo una vista de lista que quiero tener un pequeño WebBrowser a la izquierda, y el contenido a la derecha, y para enlazar el origen de cada WebBrowser con el URI en cada objeto vinculado al elemento de la lista.databind la propiedad Source del WebBrowser en WPF

Esto es lo que tengo como una prueba de concepto hasta el momento, pero el "<WebBrowser Source="{Binding Path=WebAddress}"" no compila.

<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

* empujar * para corregir su publicación. – Donnelle

Respuesta

138

El problema es que WebBrowser.Source no es una propiedad de dependencia. Una solución alternativa sería usar algo de magia AttachedProperty para habilitar esta habilidad.

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

} 

Luego, en sus xaml hacer:

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

Obteniendo una excepción en ese "nuevo Uri (uri)" ya que la cadena es "". Quizás debería ser ... browser.Source = string.IsNullOrEmpty (uri)? null: nuevo Uri (uri); – midspace

+3

Tenga en cuenta que esto es solo un enlace unidireccional y la propiedad BindableSource no cambiará cuando cambie la página del navegador web. – Kurren

+0

Eres un salvavidas. Esto funcionó perfectamente. –

26

me escribió un control de usuario envoltura, que hace uso de los DependencyProperties:

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

y usarlo de esta manera:

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

El único problema con esto es que el control WebBrowser no es "puro" WPF ... en realidad es sólo un envoltorio para un componente de Win32. Esto significa que el control no respetar el índice z, y siempre superponer otro elemento (por ejemplo: en un ScrollViewer esto podría causar algunos problemas) más información sobre estos temas en Win32 WPF en MSDN

+0

Esto es exactamente lo que necesitaba ya que quiero mostrar mi propio html. Limpio, simple, y casi entiendo lo que está haciendo (-: – Murph

+0

Funciona como un campeón, gracias! –

1

También le use un especial separate proxy control. Es aplicable no solo al caso WebBrowser, sino a cualquier control de este tipo.

3

Genial idea Todd.

He hecho algo similar con RichTextBox.Selection.Text en Silverlight 4 ahora. Gracias por su publicación. Funciona bien.

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

Aquí está el código Xaml.

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

He modificado excelente respuesta de Todd un poco para producir una versión que hace frente a cadenas o Uris de la fuente Encuadernación:

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

Es necesario declarar que en las primeras líneas de xaml el archivo que se apunta al archivo de clase

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

Esto no proporciona mucho apoyo para resolver el problema. – Woot4Moo

0

Este es un refinamiento a Todd y la respuesta de Samuel a tomar ventaja de algunas premisas básicas de la lógica, así como nosotros e el operador nulo coalescente ..

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. Si el navegador es nulo o la ubicación es nula, no podemos usar o navegar a una página nula.
  2. Cuando los elementos en el n. ° 1 no son nulos, al asignar, si el nuevo valor es un URI, utilícelo. Si no es así y el URI es nulo, entonces se unirá porque tiene que ser una cadena que se puede poner en un URI; ya que el n. ° 1 impone que la cadena no puede ser nula.
Cuestiones relacionadas