¿Alguien sabe cómo enlazar datos de 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 contenido a la derecha, y vincular el origen de cada WebBrowser con el URI en cada objeto vinculado al elemento de la lista.
Esto es lo que tengo como prueba de concepto hasta ahora, pero el " <WebBrowser Source="{Binding Path=WebAddress}"
" no se 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>
He modificado un poco la excelente respuesta de Todd para producir una versión que se adapte a las cadenas o Uris de la fuente de enlace:
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; }
fuente
Escribí un control de usuario de envoltura, que hace uso de 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 úsalo así:
<Controls:HtmlBox HtmlText="{Binding MyHtml}" />
El único problema con este es que el control WebBrowser no es wpf "puro" ... en realidad es solo un contenedor para un componente win32. Esto significa que el control no respetará el índice z y siempre se superpondrá a otro elemento (por ejemplo: en un visor de desplazamiento esto podría causar algunos problemas) más información sobre estos problemas de win32-wpf en MSDN
fuente
Genial idea, Todd.
He hecho algo similar con RichTextBox.Selection.Text en Silverlight 4 ahora. Gracias por tu 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}"/>
fuente
También puede utilizar un control de proxy especial por separado . Es aplicable no solo al caso de WebBrowser, sino a cualquier control de este tipo.
fuente
Este es un refinamiento de la respuesta de Todd y Samuel para aprovechar algunas premisas lógicas básicas, así como para usar el operador de fusión nulo.
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); }
fuente
Debe declararlo en las primeras líneas del
xaml
archivo que apunta al archivo de clasexmlns:reportViewer="clr-namespace:CoMS.Modules.Report"
fuente