ChoosingItemContainerEvent或ItemTemplateSelector

时间:2016-10-18 12:50:48

标签: listview uwp uwp-xaml

我有一个列表视图的3个数据模板。我应该使用什么来为传入的项目分配模板 - ItemTemplateSelector或附加到列表视图的ChoosingItemContainer事件?

到目前为止我一直在使用ItemTemplateSelector,但是当我快速滚动列表时,它会出现异常,可能是因为虚拟化。自动生成尝试将首先添加的项添加到当前添加项的数据类型。你能解释一下这种行为吗?

这是我面临的问题的虚拟版本

public class Person
{
    public PersonType Type;

    public string Name;
}

public enum PersonType
{
    Employee, Student, Manager
}

public class Employee : Person
{
    public string Id;
}

public class Student : Person
{
    public string CollegeName;
}

public class Manager : Person
{
    public string Level;
}

在MainPage.xaml中,我有以下DataTemplates和ItemTemplateSelector

    <DataTemplate x:Key="EmployeeTemplate" x:DataType="local:Employee">
        <StackPanel Orientation="Horizontal" Background="Bisque">
            <TextBlock Text="{x:Bind Name}" Margin="10,0"/>
            <TextBlock Text="{x:Bind Id}" Margin="10,0"/>
        </StackPanel>
    </DataTemplate>

    <DataTemplate x:Key="StudentTemplate" x:DataType="local:Student">
        <RelativePanel Background="Aqua">
            <TextBlock x:Name="NameBlock" Text="{x:Bind Name}" Margin="10,0"/>
            <TextBlock RelativePanel.RightOf="NameBlock" Text="{x:Bind CollegeName}" Margin="10,0"/>
        </RelativePanel>
    </DataTemplate>

    <DataTemplate x:Key="ManagerTemplate" x:DataType="local:Manager">
        <Grid Background="BurlyWood">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="{x:Bind Name}" Margin="10,0"/>
            <TextBlock Grid.Column="1" Text="{x:Bind Level}" Margin="10,0"/>
        </Grid>
    </DataTemplate>

    <local:ListViewItemTemplateSelector x:Key="ItemTemplateSelector"
                                        EmployeeTemplate="{StaticResource EmployeeTemplate}"
                                        StudentTemplate="{StaticResource StudentTemplate}"
                                        ManagerTemplate="{StaticResource ManagerTemplate}"/>

当我快速滚动列表时,我在MainPage.g.cs中得到一个例外

public void DataContextChangedHandler(global::Windows.UI.Xaml.FrameworkElement sender, global::Windows.UI.Xaml.DataContextChangedEventArgs args)
        {
             global::TestApp.Employee data = args.NewValue as global::TestApp.Employee;
             if (args.NewValue != null && data == null)
             {
                throw new global::System.ArgumentException("Incorrect type passed into template. Based on the x:DataType global::TestApp.Employee was expected.");
             }
             this.SetDataRoot(data);
             this.Update();
        }

这里,args.newValue包含一个位于列表中间某处的学生项目。

1 个答案:

答案 0 :(得分:0)

这个例外不是致命的 - Visual Studio捕获所有&#34;启用&#34;异常。

如果您想避免抛出它,请将ListItemView的内容设置为null,这与虚拟机机制为该单元指定的内容不同:

protected override DataTemplate SelectTemplateCore(
    object itemViewModel,
    DependencyObject container)
{    
    var itemView = container as ListViewItem;
    if (itemView != null) {
        var content = itemView.Content;
        if (content != null && content.GetType() != itemViewModel.GetType()) {
            itemView.Content = null;
        }
    }
    ... // return DataTemplate for itemViewModel
}