views:

88

answers:

2

Hello,

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 ??

A: 

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.

Piotr Justyna
+1  A: 

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.)

Dan Puzey
Thanks for answer, I am not re-creating the collection, but, I've noticed that refreshing the items of list view causes re-creating to the item templates.
Samir Sabri
What do you mean "refreshing the items?" If you destroy and recreate the items in the collection, this has about the same effect: each item's data template gets recreated.
Dan Puzey