我使用those文章来创建Webbrowser控件的AttachedProperty,因此我可以将“BindableSource”绑定到我的公共属性“Path”。这很好,并且有一个小缺点。 在我的ViewModel构造函数中,该属性设置为:
Path = new Uri("http://microsoft.com");
当页面加载时,我导航到另一个链接,“WebBrowser.Source”属性被更改,但“WebBrowser.BindableSource”未更改。 当我点击再次设置的按钮时:
Path = new Uri("http://microsoft.com");
未调用“BindableSourcePropertyChanged”,因为该属性具有这些值。
我知道如何解决它,但它不好,因为性能降低,将Path设置为另一个URL,然后将其设置为真实URL(http://microsoft.com)。
Path = new Uri("http://google.com");
Path = new Uri("http://microsoft.com");
你能不能给我一个更好的主意,我怎么能解决它。 谢谢你提前。
答案 0 :(得分:2)
我建议将BindableSource与Navigated事件同步。 您可以通过在WebBrowserUtility类中公开另一个附加行为来实现此目的,该行为会对Navigated事件做出如下反应:
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"/>
P.S。我应该承认这个实现相当脏,因为在Navigated事件处理程序中设置BindableSource会强制触发一个额外的事件。但是这段代码可行,您可以考虑一下它的改进。
<强> EDITED 强>
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;
}
}
}
}