0

这是一个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>

问题是每次我们刷新项目时都会重新创建 ITemTemplate。因此,如果我们在列表视图中有 100 个项目,那么如果我们刷新项目,就会创建另外 100 个新的 ItemTemplate 实例!

结果,如果我们在其中一个 ItemTemplate 实例上添加 UIElements,那些添加的 UIElements 将丢失,因为旧的 ITemTemplate 被替换为新的!

创建后如何保留 ItemTemplate 实例?

4

2 回答 2

1

这不是您的模板的问题 - 这是您的数据绑定到列表控件的方式的问题。

ObservableCollection是实现INotifyCollectionChanged接口的集合。当从您的集合中添加或删除项目时,该接口会引发事件,实际上有助于ItemsControl 避免您看到的场景。

在您的代码中,您是在每次更改时重新创建集合,还是只是将项目添加到现有集合中?我的怀疑是你在做前者,这就是为什么你会看到你描述的行为(即使集合中的对象是相同的,集合本身是不同的)。

(Piotr 的解决方案仍然会在您每次重新绑定时重新创建您的所有控件 - 这只是意味着您必须自己启动重新绑定,我认为这是不太优雅且不太直观的代码。)

于 2010-05-10T13:25:29.357 回答
0

萨米尔,

这就是绑定的工作方式——如果绑定新项目,旧项目就会丢失。但是如果你想比这更聪明,你可以使用普通的、通用的 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");

这将在您需要时重新绑定所有元素,而不是在集合更改时。

于 2010-05-10T13:11:55.093 回答