我有一个带有itemsource的树视图,其中包含自定义类TreeViewItem的项目。
我有一个属性selectedtreeviewitemviewModel type teeviewitem。
public TreeviewItem SelectedTreeviewItemViewModel //with INPC
我在窗口上的其他地方有一个内容控件
<ContentControl Content="{Binding SelectedTreeviewItemViewModel}" />
使用DatateMplate如下:
<DataTemplate DataType="{x:Type TreeviewItem}">
<uc:TreeviewCustomView />
</DataTemplate>
当我单击树视图的项目时,触发了selectedIteMchanged的事件,并设置了SelectedTreeViewItemViewModel,迫使ContentControl刷新其内容。
逻辑很好,但是我注意到,当我单击TreeView中的新项目时,会更新一些数据,但我不介入用户控件的构造函数(uc:treeviewCustomView)。
是否涉及某种虚拟化?我猜WPF缓存了DataTemplate;是否有任何方法可以强迫WPF每次单击树景项目时从头开始重新创建用户控件(从而踏入构造函数)?
treeViews在使用绑定时默认情况下是虚拟化的。如果将模式切换到virtualizingpanel.virtualizationmode =" standard"而不是"回收"构造函数。
这是我的窍门:
i创建一个模板选择器,该模板选择器基本上将模板包裹在另一个模板中,从而迫使创建新实例。请记住,这可能会导致严重的问题!
在我的XAML中,我从命名数据模板开始:
<DataTemplate x:Key="TreeviewItemTemplate" DataType="{x:Type TreeviewItem}">
<uc:TreeviewCustomView />
</DataTemplate>
然后我创建一个模板选择器如下:
public class TreeviewItemTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item == null)
{
return null;
}
var declaredDataTemplate = ((FrameworkElement)container).FindResource("TreeviewItemTemplate") as DataTemplate;
var wrappedDataTemplate = WrapDataTemplate(declaredDataTemplate );
return wrappedDataTemplate;
}
private static DataTemplate WrapDataTemplate(DataTemplate declaredDataTemplate)
{
var frameworkElementFactory = new FrameworkElementFactory(typeof(ContentPresenter));
frameworkElementFactory.SetValue(ContentPresenter.ContentTemplateProperty, declaredDataTemplate);
var dataTemplate = new DataTemplate();
dataTemplate.VisualTree = frameworkElementFactory;
return dataTemplate;
}
}
最后,我在内容控件上使用了选择器:
<ContentControl Content="{Binding SelectedTreeviewItemViewModel }"
ContentTemplateSelector="{StaticResource TreeviewItemTemplateSelector }" />