WPF: How can I KEEP the same ItemTemplate instance once its created?
Here is a cinario:
I have a ListView, with ItemsSource = ProjectModel.Instance.PagesModelsCollection;
where PagesModelsCollection is an ObservableCollection
开发者_开发知识库In the ListView XAML part:
<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>
The problem is the ITemTemplate is re-created each time we refresh the Items. So, if we have 100 Item in the list view, another 100 new ItemTemplate instance will be created if we refresh the items!
As a result, if we add UIElements on one of the ItemTemplate intances, those added UIElements will be lost, because the old ITemTemplate is replaced with a new one!
How can I KEEP the ItemTemplate instance once its created ??
This isn't a problem with your template - it's a problem with the way your data is bound to your list control.
ObservableCollection
is a collection that implements the INotifyCollectionChanged
interface. That interface raises events when items are added or removed from your collection and actually helps an ItemsControl
avoid the scenario you're seeing.
In your code, are you re-creating the collection each time it changes, or are you just adding items to the existing collection? My suspicion is that you're doing the former, which is why you'll see the behaviour you describe (even if the objects in the collection are the same, the collection itself is different).
(Piotr's solution will still cause all of your controls to be recreated every time you re-bind - it just means that you will have to initiate rebinding yourself, which I would contend is less elegant and less intuitive code.)
Samir,
This is the way binding works - if you bind new items, old ones are lost. But if you want to be smarter than this you can use plain, generic List instead of ObservableCollection and implement INotifyPropertyChanged
in a class holding this collection (your DataContext) to bind list elements just when you want it. For example:
#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
And then, when you want to rebind items, you can simple call something like this:
//when your collection changes and you're sure you want to rebind it:
OnPropertyChanges("YourCollectionName");
This will rebind all elements when you need it, not when collection changes.
精彩评论