時間があれば、新しい空のアプリ (XAML)テンプレートを作成し、次の XAML コードを記述します。
コンテナーのリサイクルが機能しないように見えるため、 WPF アプリケーションを作成しても無駄だと思います。また、GridViewをListViewに置き換える必要があります。
<Page.Resources>
<vm:MainViewModel x:Key="Main" />
</Page.Resources>
<Page.DataContext>
<Binding Source="{StaticResource Main}" />
</Page.DataContext>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"
VerticalAlignment="Center">
<Grid.Resources>
<Style x:Key="GridViewStyle1"
TargetType="GridView">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridView">
<ScrollViewer HorizontalSnapPointsAlignment="Near"
HorizontalSnapPointsType="MandatorySingle">
<ItemsPresenter VirtualizingStackPanel.VirtualizationMode="Standard" />
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<GridView Style="{StaticResource GridViewStyle1}"
ItemsSource="{Binding Items}"
SelectionMode="None">
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
Loaded="StackPanel_Loaded">
<Grid Width="800"
Height="400">
<ScrollViewer HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Visible">
<Border Background="#b7d84b">
<TextBlock Foreground="Black"
Text="{Binding Message}" />
</Border>
</ScrollViewer>
</Grid>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
ビュー モデルとアイテムクラスを作成します。
public class MainViewModel
{
private const int NumberOfItems = 10000;
public ObservableCollection<Item> Items
{
get;
private set;
}
public MainViewModel()
{
var tempCollection = new ObservableCollection<Item>();
for (var index = 0; index < NumberOfItems; ++index)
{
var item = new Item
{
Id = index,
Message = GetMessage(index)
};
tempCollection.Add(item);
}
Items = tempCollection;
}
private string GetMessage(int index)
{
var sb = new StringBuilder();
for(var i = 0; i < 100; ++i)
{
sb.Append("...\n");
}
sb.Append("This is item #");
sb.Append(index);
return sb.ToString();
}
}
public class Item
{
public string Message { get; set; }
public int Id { get; set; }
}
アプリを起動すると、一連の項目をスクロールできます。特定のアイテムを縦にスクロールして「This is item #x」というメッセージが表示されると、右にスクロールした後に「This is item #x」という別のメッセージが再び表示されることに気付きました (ただし、スクロールしませんでした)。アイテムを垂直にします。)
これは、アイテムが仮想化されているためです。そして、アイテムが実現すると、プールからコンテナーが使用されます。運が悪ければ、コンテナーは既にスクロールされています...
プールには 10 個のアイテムがあります。
コード ビハインド ファイル:
private readonly DateTime _start;
public MainPage()
{
this.InitializeComponent();
_start = DateTime.Now;
}
[Conditional("DEBUG")]
public void WriteDebugMessage(string message)
{
var span = DateTime.Now - _start;
Debug.WriteLine(
"{0:D2}:{1:D2}:{2:D3} - {3}",
span.Minutes,
span.Seconds,
span.Milliseconds,
message);
}
private void StackPanel_Loaded(object sender, RoutedEventArgs e)
{
WriteDebugMessage("StackPanel loaded.");
}
次に、ItemsPresenter オブジェクトを再キャストします。
<ItemsPresenter VirtualizingStackPanel.VirtualizationMode="Standard"/>
それが機能したとしても、パフォーマンスは向上しません。
問題のエレガントな解決策を知っている人はいますか? public フィールドが多すぎるためにクビになりたくない ;) 添付プロパティを書くことも考えました...