누구든지 WPF (3.5SP1)에서 WebBrowser의 .Source 속성을 데이터 바인딩하는 방법을 알고 있습니까? 왼쪽에는 작은 WebBrowser가 있고 오른쪽에는 콘텐츠가 있고 목록 항목에 바인딩 된 각 개체의 URI를 사용하여 각 WebBrowser의 소스를 데이터 바인딩하려는 목록보기가 있습니다.
이것이 지금까지 개념 증명으로 가지고있는 것이지만 ” <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>
답변
문제는 즉 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;
}
}
}
그런 다음 xaml에서 다음을 수행하십시오.
<WebBrowser ns:WebBrowserUtility.BindableSource="{Binding WebAddress}"/>
답변
나는 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;
}
답변
DependencyProperties를 사용하는 래퍼 usercontrol을 작성했습니다.
XAML :
<UserControl x:Class="HtmlBox">
<WebBrowser x:Name="browser" />
</UserControl>
씨#:
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);
}
}
다음과 같이 사용하십시오.
<Controls:HtmlBox HtmlText="{Binding MyHtml}" />
이것의 유일한 문제점은 WebBrowser 컨트롤이 “순수한”wpf가 아니라는 것입니다. 실제로 win32 구성 요소의 래퍼 일뿐입니다. 즉, 컨트롤이 z-index를 존중하지 않고 항상 다른 요소를 오버레이합니다 (예 : scrollviewer에서 문제가 발생할 수 있음) MSDN의 win32-wpf 문제에 대한 자세한 정보
답변
멋진 아이디어 토드.
이제 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;
}
}
}
다음은 Xaml-Code입니다.
<RichTextBox IsReadOnly='False' TextWrapping='Wrap' utilities:RichTextBoxHelper.BindableSelectionText="{Binding Content}"/>
답변
특수한 별도의 프록시 제어를 사용할 수도 있습니다 . WebBrowser 사례뿐만 아니라 그러한 모든 제어에도 적용 할 수 있습니다.
답변
이것은 일부 기본 논리 전제를 활용하고 null 병합 연산자를 사용하기 위해 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);
}
- 브라우저가 null이거나 위치가 null이면 null 페이지를 사용하거나 탐색 할 수 없습니다.
- # 1의 항목이 null이 아닌 경우 할당 할 때 새 값이 URI이면이를 사용합니다. 그렇지 않고 URI가 null 인 경우 결합은 URI에 넣을 수있는 문자열이어야합니다. # 1은 문자열이 null 일 수 없도록 강제하기 때문입니다.
답변
xaml
클래스 파일을 가리키는 파일 의 처음 몇 줄에서 선언해야 합니다.
xmlns:reportViewer="clr-namespace:CoMS.Modules.Report"