Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 导航时更改WebBrowser的AttachedProperty_C#_Wpf_Mvvm_Browser - Fatal编程技术网

C# 导航时更改WebBrowser的AttachedProperty

C# 导航时更改WebBrowser的AttachedProperty,c#,wpf,mvvm,browser,C#,Wpf,Mvvm,Browser,我使用了一篇文章来创建Webbrowser控件的AttachedProperty,因此我可以将“BindableSource”绑定到我的公共属性“Path”。这是伟大的和工作良好的一个小缺点。 在我的ViewModel构造函数中,属性设置为: Path = new Uri("http://microsoft.com"); 加载页面时,我导航到另一个链接,“WebBrowser.Source”属性已更改,但“WebBrowser.BindableSource”未更改。 当我单击再次设置的按钮时:

我使用了一篇文章来创建Webbrowser控件的AttachedProperty,因此我可以将“BindableSource”绑定到我的公共属性“Path”。这是伟大的和工作良好的一个小缺点。 在我的ViewModel构造函数中,属性设置为:

Path = new Uri("http://microsoft.com");
加载页面时,我导航到另一个链接,“WebBrowser.Source”属性已更改,但“WebBrowser.BindableSource”未更改。 当我单击再次设置的按钮时:

 Path = new Uri("http://microsoft.com");
未调用“BindableSourcePropertyChanged”,因为该属性具有这些值

我有一个解决方法,但效果不好,因为性能会变慢,需要将路径设置为另一个URL,然后再将其设置为真实URL()

你能不能给我一个更好的主意,我怎样才能解决它。
感谢高级版。

我建议将BindableSource与导航事件同步。 您可以通过在WebBrowserUtility类中公开另一个附加行为来实现这一点,该行为会对导航事件做出如下反应:

    public static readonly DependencyProperty ShouldHandleNavigatedProperty =
        DependencyProperty.RegisterAttached(
            "ShouldHandleNavigated", 
            typeof(Boolean), 
            typeof(WebBrowserUtility), 
            new UIPropertyMetadata(false, ShouldHandleNavigatedPropertyChanged));

    public static Boolean GetShouldHandleNavigated(DependencyObject obj)
    {
        return (Boolean)obj.GetValue(BindableSourceProperty);
    }

    public static void SetShouldHandleNavigated(DependencyObject obj, Boolean value)
    {
        obj.SetValue(ShouldHandleNavigatedProperty, value);
    }

    public static void ShouldHandleNavigatedPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        WebBrowser browser = o as WebBrowser;
        if (browser != null)
        {
            if ((bool)e.NewValue)
            {
                browser.Navigated += new NavigatedEventHandler(Browser_Navigated);
            }
            else
            {
                browser.Navigated -= new NavigatedEventHandler(Browser_Navigated);
            }
        }
    }

    private static void Browser_Navigated(object sender, NavigationEventArgs e)
    {
        WebBrowser browser = sender as WebBrowser;
        if (browser != null)
        {
            browser.SetValue(WebBrowserUtility.BindableSourceProperty, browser.Source.AbsoluteUri);
        }
    }
xaml中的用法:

<WebBrowser self:WebBrowserUtility.BindableSource="{Binding WebAddress}"
            self:WebBrowserUtility.ShouldHandleNavigated="True"/>  

谢谢,伙计,你的解决方案是无错误的,但不能解决我的问题,因为在某些页面上我使用了POST请求。它将导航到同一页面两次,因此在导航时,完整的BindableSourceProperty将被更改,webbrowser将导航到同一页面。如果我使用Post请求,我会遇到麻烦。但在某些情况下,这可能会很有用。事实上,我已经在体育课上承认了这个问题。我刚刚建议你打开想象力,自己解决这个问题。解决方案是显而易见的:在Browser_中,在Browser.SetValue(…)之前导航处理程序,您应该设置一些标志,并立即在Browser.SetValue(…)之后重置它。然后在BindableSourcePropertyChanged处理程序中,如果设置了此标志,则应跳过对BindableSourceProperty的更改。正确的方法是公开另一个附加属性,但在上面的示例中,我使用Tag属性获得了预期的结果。谢谢。这个解决方案今天帮助了我。
<WebBrowser self:WebBrowserUtility.BindableSource="{Binding WebAddress}"
            self:WebBrowserUtility.ShouldHandleNavigated="True"/>  
    public static class WebBrowserUtility
    {
        ...
        private const string _SkipSourceChange = "Skip";

        public static void BindableSourcePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            WebBrowser browser = o as WebBrowser;
            if (browser != null)
            {
                string uri = e.NewValue as string;
                if (!_SkipSourceChange.Equals(browser.Tag))
                {
                    browser.Source = uri != null ? new Uri(uri) : null;
                }
            }
        }

        private static void Browser_Navigated(object sender, NavigationEventArgs e)
        {
            WebBrowser browser = sender as WebBrowser;
            if (browser != null)
            {
                if (WebBrowserUtility.GetBindableSource(browser) != e.Uri.ToString())
                {
                        browser.Tag = _SkipSourceChange;
                        browser.SetValue(WebBrowserUtility.BindableSourceProperty, browser.Source.AbsoluteUri);
                        browser.Tag = null;
                }
            }
        }
    }