这是一个cinario:
我有一个ListView,ItemsSource = ProjectModel.Instance.PagesModelsCollection;
其中PagesModelsCollection是ObservableCollection
在ListView XAML部分中:
<ListView.ItemTemplate>
<DataTemplate x:Name="PagesViewDataTemplate">
<DataTemplate.Resources>
<Style x:Key="PageHostStyle" TargetType="{x:Type p:KPage}">
</Style>
</DataTemplate.Resources>
<StackPanel x:Name="MarginStack" Margin="50,50,50,50" >
<p:KPage x:Name="PageHost" >
</p:KPage>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
问题是每次刷新Items时都会重新创建ITemTemplate。 所以,如果我们在列表视图中有100个Item,那么如果我们刷新项目,将会创建另外100个新的ItemTemplate实例!
因此,如果我们在其中一个ItemTemplate插件中添加UIElements,那些添加的UIElements将会丢失,因为旧的ITemTemplate将替换为新的![/ p>
如何在创建ItemTemplate实例后保持它?
答案 0 :(得分:1)
这不是您的模板的问题 - 这是您的数据绑定到列表控件的方式的问题。
ObservableCollection
是一个实现INotifyCollectionChanged
接口的集合。在您的收藏中添加或删除项目时,该界面会引发事件,实际上有助于ItemsControl
避免您正在看到的情景。
在您的代码中,您是在每次更改时重新创建集合,还是只是将项目添加到现有集合中?我怀疑你是在做前者,这就是为什么你会看到你描述的行为(即使集合中的对象是相同的,集合本身也不同)。
(Piotr的解决方案仍然会在每次重新绑定时重新创建所有控件 - 这只意味着你必须自己重新启动重新绑定,我认为这不是优雅和不太直观的代码。)
答案 1 :(得分:0)
萨米尔,
这是绑定的方式 - 如果绑定新项目,旧项目将丢失。但是如果你想比这更聪明,你可以使用普通的,通用的List而不是ObservableCollection,并在一个持有这个集合的类(你的DataContext)中实现INotifyPropertyChanged
,以便在你需要时绑定列表元素。例如:
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
然后,当你想要重新绑定项目时,你可以简单地调用这样的东西:
//when your collection changes and you're sure you want to rebind it:
OnPropertyChanges("YourCollectionName");
这将在您需要时重新绑定所有元素,而不是在集合更改时重新绑定。