我正在开发一个 WPF MVVM 应用程序。我正在寻找将 WebBrowser 控件数据绑定(bind)到 View 模型,该 View 模型又绑定(bind)到选项卡。遵循 article 中的建议,我创建了一个由静态 DependancyProperty 组成的静态助手类:
public static class WebBrowserHelper
{
public static readonly DependencyProperty BodyProperty =
DependencyProperty.RegisterAttached("Body", typeof(string), typeof(WebBrowserHelper), new PropertyMetadata(OnBodyChanged));
public static string GetBody(DependencyObject dependencyObject)
{
return (string)dependencyObject.GetValue(BodyProperty);
}
public static void SetBody(DependencyObject dependencyObject, string body)
{
dependencyObject.SetValue(BodyProperty, body);
}
private static void OnBodyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
string newValue = (string)e.NewValue;
var webBrowser = (WebBrowser)d;
webBrowser.NavigateToString(newValue);
}
}
XAML 将 WebBrowser 绑定(bind)到 DependancyProperty:
<WebBrowser Grid.Column="2" HorizontalAlignment="Center" src:WebBrowserHelper.Body="{Binding HTMLBody}" VerticalAlignment="Center" Height="Auto" Width="Auto" />
绑定(bind)到 Tab Control 的 ItemsSource 的 ViewModel:
public class SomeVM : ViewModelBase, INotifyPropertyChanged
{
private string _htmlBody;
private SomeView _myView = new SomeView();
public SomeVM (string tabName)
{
TabName = tabName;
string contentsAsHTML = do_a_whole_bunch_of_stuff_to_generate_an_HTML_string();
HTMLBody = contentsAsHTML;
}
public string HTMLBody
{
get { return _htmlBody; }
set
{
if (_htmlBody != value)
{
_htmlBody = value;
RaisePropertyChanged("HTMLBody");
}
}
}
public SomeView View
{
get {return _myView;}
set { }
}
public string TabName { get; set; }
}
MainViewModel,创建 Tab 集合:
private ObservableCollection<SomeVM> _tabs;
public ObservableCollection<SomeVM> Tabs
{
get
{
if (_tabs== null)
{
_tabs= new ObservableCollection<SomeVM>();
_tabs.Add(new SomeVM("Tab 1"));
_tabs.Add(new SomeVM("Tab 2"));
_tabs.Add(new SomeVM("Tab 3"));
}
return _tabs;
}
}
MainWindow.xaml 设置选项卡绑定(bind):
<TabControl ItemsSource="{Binding Tabs, Source={StaticResource vm}}"
>
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding TabName}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding View}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
我的问题是“OnBodyChanged”在标签更改时被多次触发。 HTML 需要几秒钟来加载,我宁愿它只在 View 模型中实际修改属性时加载。
编辑
Here's the smallest sample project that recreates my problem .
最佳答案
您的问题与附加属性或 MVVM 无关。
事实上,真正的问题是 TabControl 每次更改所选选项卡时都会破坏并重新创建其子项。这可以解释为什么处理程序被多次调用。 VisualTree 仅包含选定的选项卡。
如果您可以尝试使用其他控件,您将看到没有错误。
为了解决这个问题,我会把你重定向到这个 post .
关于wpf - DependencyProperty.RegisterAttached 和多个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12691328/