如果您有时间,请创建一个新的空白应用 (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>
创建视图模型和Item类:
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; }
}
启动应用程序时,您可以滚动浏览一系列项目。我注意到,当您垂直滚动特定项目以便可以看到“这是项目#x”消息时,您会在向右滚动后再次看到另一条消息“这是项目#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"/>
如果它有效,它不会提高性能。
有谁知道这个问题的优雅解决方案?我不想因为公共领域太多而被解雇;)我还考虑过写一个附加属性...