C# 数据绑定 WPF 中 WebBrowser 的 Source 属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/263551/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
databind the Source property of the WebBrowser in WPF
提问by Russ
Does anyone know how to databind the .Source property of the WebBrowser in WPF ( 3.5SP1 )? I have a listview that I want to have a small WebBrowser on the left, and content on the right, and to databind the source of each WebBrowser with the URI in each object bound to the list item.
有谁知道如何在 WPF ( 3.5SP1 ) 中对 WebBrowser 的 .Source 属性进行数据绑定?我有一个列表视图,我希望左侧有一个小的 WebBrowser,右侧有一个内容,并将每个 WebBrowser 的源与绑定到列表项的每个对象中的 URI 进行数据绑定。
This is what I have as a proof of concept so far, but the "<WebBrowser Source="{Binding Path=WebAddress}"
" does not compile.
到目前为止,这是我作为概念证明的内容,但“ <WebBrowser Source="{Binding Path=WebAddress}"
”无法编译。
<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>
采纳答案by Todd White
The problem is that WebBrowser.Source
is not a DependencyProperty
. One workaround would be to use some AttachedProperty
magic to enable this ability.
问题是这WebBrowser.Source
不是一个DependencyProperty
. 一种解决方法是使用一些AttachedProperty
魔法来启用此功能。
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:
然后在您的 xaml 中执行以下操作:
<WebBrowser ns:WebBrowserUtility.BindableSource="{Binding WebAddress}"/>
回答by RoelF
I wrote a wrapper usercontrol, which makes use of the DependencyProperties:
我编写了一个包装器用户控件,它使用了 DependencyProperties:
XAML:
XAML:
<UserControl x:Class="HtmlBox">
<WebBrowser x:Name="browser" />
</UserControl>
C#:
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);
}
}
and use it like so:
并像这样使用它:
<Controls:HtmlBox HtmlText="{Binding MyHtml}" />
The only trouble with this one is that the WebBrowser control is not "pure" wpf... it is actually just a wrapper for a win32 component. This means that the control won't respect the z-index, and will always overlay other element (eg: in a scrollviewer this might cause some trouble) more info about these win32-wpf issues on MSDN
这个唯一的问题是 WebBrowser 控件不是“纯”wpf……它实际上只是一个 win32 组件的包装器。这意味着控件不会尊重 z-index,并且将始终覆盖其他元素(例如:在滚动查看器中这可能会导致一些麻烦)有关MSDN上这些 win32-wpf 问题的更多信息
回答by Max Galkin
You may also use a special separate proxy control. It's applicable not only to the WebBrowser case, but to any such control.
您还可以使用特殊的单独代理控件。它不仅适用于 WebBrowser 情况,也适用于任何此类控件。
回答by Olaf Japp
Cool idea Todd.
好主意托德。
I have done similar with the RichTextBox.Selection.Text in Silverlight 4 now. Thanks for your post. Works fine.
我现在对 Silverlight 4 中的 RichTextBox.Selection.Text 做了类似的处理。谢谢你的帖子。工作正常。
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;
}
}
}
Here is the Xaml-Code.
这是 Xaml 代码。
<RichTextBox IsReadOnly='False' TextWrapping='Wrap' utilities:RichTextBoxHelper.BindableSelectionText="{Binding Content}"/>
回答by Samuel Hyman
I've amended Todd's excellent answer a little to produce a version that copes with either strings or Uris from the Binding source:
我稍微修改了 Todd 的优秀答案,以生成一个可以处理来自 Binding 源的字符串或 Uris 的版本:
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;
}
回答by William
You need to declare it at the first few lines of the xaml
file which is pointing to the class file
您需要在xaml
指向类文件的文件 的前几行中声明它
xmlns:reportViewer="clr-namespace:CoMS.Modules.Report"
回答by ΩmegaMan
This is a refinement to Todd's and Samuel's answer to take advantage of some basic logic premises as well as use the null coalescing operator..
这是对 Todd 和 Samuel 的回答的改进,以利用一些基本的逻辑前提以及使用空合并运算符..
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);
}
- If the browser is null or the location is null, we cannot use or navigate to a null page.
- When the items in #1 are not null then when assigning, if the new value is a URI then use it. If not and the URI is null, then coalesce for it has to be a string which can be put into a URI; since #1 enforces that the string cannot be null.
- 如果浏览器为空或位置为空,我们将无法使用或导航到空页面。
- 当 #1 中的项目不为 null 时,则在分配时,如果新值是 URI,则使用它。如果不是并且 URI 为空,则合并它必须是一个可以放入 URI 的字符串;因为#1 强制字符串不能为空。