2016-10-18 4 views
0

私はリストビュー用に3つのデータテンプレートを持っています。着信アイテムにテンプレートを割り当てるにはどうすればよいですか?ItemTemplateSelectorまたはChoiceItemContainerイベントがリストビューに添付されていますか?ChoosingItemContainerEventまたはItemTemplateSelector

これまでItemTemplateSelectorを使用していましたが、おそらく仮想化のためにリストをすばやくスクロールすると例外が発生します。自動生成されたアイテムは、最初に追加されたアイテムのデータ型に追加されたアイテムを型キャストしようとします。あなたはこの行動を説明できますか?ここで

私はMainPage.xamlをで

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

を直面しています、問題のダミー版で、私は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で例外を取得します。リストをすばやくスクロールしたときに表示されます。

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にはリストの真ん中にある学生用アイテム。

+0

私はアイテムセレクタで仮想化interfersはないと思うが。 – disklosr

+1

おそらくそうではありません。しかし、新しいアイテムが、異なるデータタイプの古いアイテムによって占められているコンテナに埋められているのはなぜですか? – Abhijeet

+0

非常に単純なアイテムとそれらのDataTemplates、およびそれらを選択するためのDataTemplateSelectorはまったく同じ問題です。コンパイルされたバインディングも使用します。また、仮想化の疑いがあるとクラッシュにつながってしまう。あなたは解決策を見つけましたか? – myself

答えて

0

この例外は致命的ではありません - Visual Studioはすべての "有効"例外をキャッチします。

あなたはそれがスローされないようにしたい場合は、仮想化機構は、セルのために指定されたものと異なる場合、nullにListItemViewの内容を設定します。

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 
} 
関連する問題