WPF:如何创建相同的ItemTemplate实例?

时间:2010-05-10 10:47:06

标签: wpf itemtemplate

这是一个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实例后保持它?

2 个答案:

答案 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");

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