我建议将 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"/>
附:我应该承认这个实现相当肮脏,因为在 Navigated 事件处理程序中设置 BindableSource 会强制触发一个额外的事件。但是此代码有效,您可以考虑对其进行改进。
已编辑
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;
}
}
}
}