ค้นหาคุณสมบัติ Source ของ WebBrowser ใน WPF


86

ไม่มีใครรู้วิธีการหาฐานข้อมูลคุณสมบัติ. Source ของ WebBrowser ใน WPF (3.5SP1)? ฉันมี listview ที่ฉันต้องการมีเว็บเบราว์เซอร์ขนาดเล็กทางด้านซ้ายและเนื้อหาทางด้านขวาและเพื่อค้นหาแหล่งที่มาของเว็บเบราว์เซอร์แต่ละรายการด้วย URI ในแต่ละวัตถุที่เชื่อมโยงกับรายการ

นี่คือสิ่งที่ฉันมีเป็นหลักฐานยืนยันถึงแนวคิด แต่ " <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>

คำตอบ:


158

ปัญหา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}"/>

9
ได้รับข้อยกเว้นว่า "Uri ใหม่ (uri)" เป็นสตริงคือ "" บางทีมันควรจะเป็น .... browser.Source = string.IsNullOrEmpty (uri)? null: Uri ใหม่ (uri);
กลางอวกาศ

5
โปรดทราบว่านี่เป็นเพียงวิธีเดียวในการผูกและคุณสมบัติ BindableSource จะไม่เปลี่ยนแปลงเมื่อหน้าเว็บเบราว์เซอร์เปลี่ยนไป
Kurren

1
ในฐานะมือใหม่นี่เป็นเรื่องยากสำหรับฉันที่จะติดตามการเขียนบางอย่างเกี่ยวกับการมีตัวตั้งค่าเริ่มต้นสาธารณะสำหรับ "WebAddress" ใน ViewModel ที่ถูกผูกไว้พร้อมกับเหตุการณ์การอัปเดตสำหรับการเปลี่ยนแปลงคุณสมบัติจะช่วยได้ โครงการนี้มีตัวอย่างที่คล้ายกัน github.com/thoemmi/WebBrowserHelper
pgee70

ขอบคุณ. ฉันเอาสิ่งนี้และแก้ไขเพื่อใช้คุณสมบัติ "Html" ซึ่งเรียก NavigateToString ภายใต้ประทุน
Antony Scott

@ pgee70 ขอบคุณฉันทำตามตัวอย่าง github ของคุณและทำการรักษา
percentum

33

ฉันได้แก้ไขคำตอบที่ยอดเยี่ยมของทอดด์เล็กน้อยเพื่อสร้างเวอร์ชันที่จัดการกับสตริงหรือ Uris จากแหล่ง Binding:

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

31

ฉันเขียน usercontrol wrapper ซึ่งใช้ประโยชน์จาก DependencyProperties:

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}"  />

ปัญหาเดียวของปัญหานี้คือการควบคุมเว็บเบราว์เซอร์ไม่ใช่ wpf "บริสุทธิ์" ... จริงๆแล้วมันเป็นเพียงตัวห่อสำหรับส่วนประกอบ win32 ซึ่งหมายความว่าตัวควบคุมจะไม่เคารพดัชนี z และจะซ้อนทับองค์ประกอบอื่น ๆ เสมอ (เช่นใน scrollviewer อาจทำให้เกิดปัญหา) ข้อมูลเพิ่มเติมเกี่ยวกับปัญหา win32-wpf บนMSDN


นี่คือสิ่งที่ฉันต้องการเนื่องจากฉันต้องการแสดง html ของตัวเอง เรียบร้อยเรียบง่ายและฉันเกือบจะเข้าใจว่ามันทำอะไร (-:
Murph

3

ทอดด์ไอเดียเจ๋ง

ฉันทำคล้ายกับ RichTextBox.Selection.Text ใน Silverlight 4 แล้ว ขอบคุณสำหรับโพสต์ของคุณ ใช้งานได้ดี

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

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

1

นอกจากนี้คุณยังอาจใช้เป็นพิเศษควบคุมพร็อกซี่ที่แยกต่างหาก ไม่เพียง แต่ใช้ได้กับกรณีของเว็บเบราว์เซอร์เท่านั้น แต่ยังใช้ได้กับการควบคุมดังกล่าวด้วย


0

นี่เป็นการปรับแต่งคำตอบของทอดด์และซามูเอลเพื่อใช้ประโยชน์จากสถานที่ลอจิกพื้นฐานบางอย่างรวมทั้งใช้ตัวดำเนินการการรวมกันเป็นโมฆะ ..

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. หากเบราว์เซอร์เป็นโมฆะหรือตำแหน่งเป็นโมฆะเราจะไม่สามารถใช้หรือไปที่หน้าว่างได้
  2. เมื่อรายการใน # 1 ไม่เป็นโมฆะเมื่อกำหนดหากค่าใหม่เป็น URI ให้ใช้ ถ้าไม่ใช่และ URI เป็นโมฆะดังนั้นการรวมกันจะต้องเป็นสตริงที่สามารถใส่ลงใน URI ได้ เนื่องจาก # 1 บังคับว่าสตริงต้องไม่เป็นโมฆะ

-3

คุณต้องประกาศที่สองสามบรรทัดแรกของxamlไฟล์ซึ่งชี้ไปที่ไฟล์คลาส

xmlns:reportViewer="clr-namespace:CoMS.Modules.Report" 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.