WPF: Как я могу сохранить тот же экземпляр ItemTemplate после его создания? - PullRequest
0 голосов
/ 10 мая 2010

Вот сценарий:

У меня есть ListView, с ItemsSource = ProjectModel.Instance.PagesModelsCollection;где PagesModelsCollection представляет собой ObservableCollection

В XAML-части ListView:

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

Проблема заключается в том, что ITemTemplate создается заново каждый раз, когда мы обновляем элементы.Таким образом, если у нас есть 100 Item в виде списка, будет создан другой 100 новый экземпляр ItemTemplate, если мы обновим элементы!

В результате, если мы добавим UIElements в один из экземпляров ItemTemplate, эти добавленные UIElementsбудет потеряно, потому что старый ITemTemplate будет заменен новым!

Как я могу сохранить экземпляр ItemTemplate после его создания ??

Ответы [ 2 ]

1 голос
/ 10 мая 2010

Это не проблема с вашим шаблоном - это проблема с тем, как ваши данные связаны с вашим списком управления.

ObservableCollection - это коллекция, которая реализует интерфейс INotifyCollectionChanged. Этот интерфейс вызывает события, когда элементы добавляются или удаляются из вашей коллекции, и фактически помогает ItemsControl избежать сценария, который вы видите.

В своем коде вы заново создаете коллекцию при каждом ее изменении или просто добавляете элементы в существующую коллекцию? Я подозреваю, что вы делаете первое, поэтому вы увидите поведение, которое вы описываете (даже если объекты в коллекции совпадают, сама коллекция отличается).

(Решение Петра будет по-прежнему вызывать повторное создание всех ваших элементов управления при каждом повторном связывании - это просто означает, что вам придется инициировать повторное связывание себя, что, я бы сказал, менее элегантный и менее интуитивный код.)

0 голосов
/ 10 мая 2010

Samir,

Так работает привязка - если вы связываете новые элементы, старые теряются. Но если вы хотите быть умнее, чем это, вы можете использовать простой, универсальный List вместо ObservableCollection и реализовать INotifyPropertyChanged в классе, содержащем эту коллекцию (ваш DataContext), чтобы связывать элементы списка именно тогда, когда вы этого хотите. Например:

#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");

При этом все элементы будут перепривязаны тогда, когда вам это нужно, а не при изменении коллекции.

...