Проблема, с которой я столкнулся, заключается в том, что мой просмотр списка обновлений занимает 3-4 секунды для обновления.Я думаю, что виртуализация настроена правильно;Однако, пожалуйста, укажите, если это неверно.Мой источник элементов привязан к ICollectionView.
Если я установлю цикл на 3000+ в пользовательском интерфейсе BindingViewModel, потребуется много времени для запуска, даже если для построения ViewModels требуется меньше секунды.
Я не знаю, как прикреплять файлы, поэтому я выложу весь пример кода, который воспроизводит эту проблему:
BigList.Xaml: `
<Style x:Key="textBlockBaseStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="Blue"/>
</Style>
<Style x:Key="headerButtonStyle" TargetType="Button">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="Background" Value="Transparent" />
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkBlue"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="borderBaseStyle" TargetType="Border">
<Setter Property="BorderBrush" Value="Blue"/>
</Style>
<!--these two styles let us cascadingly style on the page without having to specify styles
apparently styles don't cascade into itemscontrols... in the items control we must reference via key -->
<Style TargetType="TextBlock" BasedOn="{StaticResource textBlockBaseStyle}"/>
<Style TargetType="Border" BasedOn="{StaticResource borderBaseStyle}"/>
<!-- hover styles -->
<Style x:Key="onmouseover" TargetType="{x:Type Border}" BasedOn="{StaticResource borderBaseStyle}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkBlue"/>
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Grid>
<StackPanel Width="390">
<!-- Header-->
<Border BorderThickness="1,1,1,1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="55"/>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="70"/>
</Grid.ColumnDefinitions>
<Button Command="{Binding SortFirstNameCommand}" Style="{StaticResource headerButtonStyle}" Grid.Column="1" >
<TextBlock TextAlignment="Left" Text="First"/>
</Button>
<Button Style="{StaticResource headerButtonStyle}" Grid.Column="2" >
<TextBlock TextAlignment="Left" Text="Last"/>
</Button>
<Button Style="{StaticResource headerButtonStyle}" Grid.Column="3" >
<TextBlock TextAlignment="Left" Text="Activity"/>
</Button>
<Button Style="{StaticResource headerButtonStyle}" Grid.Column="4">
<TextBlock TextAlignment="Left" Text="Last Activity"/>
</Button>
</Grid>
</Border>
<Border BorderThickness="1,0,1,1">
<ItemsControl VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" ItemsSource="{Binding UsersAvailForEmail}" MaxHeight="400">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer x:Name="ScrollViewer" HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto" IsDeferredScrollingEnabled="True" Padding="{TemplateBinding Padding}">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Style="{StaticResource onmouseover}" BorderThickness="0,0,1,1">
<CheckBox Margin="20,5" IsChecked="{Binding IsSelected}">
<CheckBox.Content>
<StackPanel Orientation="Horizontal">
<TextBlock Width="20"/>
<TextBlock Width="70" Style="{StaticResource textBlockBaseStyle}" Grid.Column="1" Text="{Binding FirstName}"/>
<TextBlock Width="70" Style="{StaticResource textBlockBaseStyle}" Grid.Column="2" Text="{Binding LastName}"/>
<TextBlock Width="70" Style="{StaticResource textBlockBaseStyle}" Grid.Column="3" Text="{Binding Action}"/>
<TextBlock Width="60" Style="{StaticResource textBlockBaseStyle}" Grid.Column="4" Text="{Binding ActionId}"/>
</StackPanel>
</CheckBox.Content>
</CheckBox>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
</StackPanel>
</Grid>
`
BindingViewModel.cs:
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Windows.Data;
namespace LargeItemsCollection
{
public class BindingViewModel : INotifyPropertyChanged
{
ObservableCollection<EmailPersonViewModel> _usersAvail = new ObservableCollection<EmailPersonViewModel>();
ListCollectionView _lvc = null;
public BindingViewModel()
{
for (int i = 0; i < 4000; i++)
{
_usersAvail.Add( new EmailPersonViewModel { FirstName = "f" +i.ToString() , LastName= "l" + i.ToString(), Action= "a" + i.ToString(), ActionId="ai" + i.ToString(), IsSelected=true });
}
_lvc = new ListCollectionView(_usersAvail);
}
public ICollectionView UsersAvailForEmail
{
get { return _lvc; }
}
/// <summary>
/// Raised when a property on this object has a new value.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises this object's PropertyChanged event.
/// </summary>
/// <param name="propertyName">The property that has a new value.</param>
public virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
}
EmailPersonViewModel.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LargeItemsCollection
{
public class EmailPersonViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Action { get; set; }
public string ActionId { get; set; }
public bool IsSelected { get; set; }
public EmailPersonViewModel()
{
}
}
}
MainWindow.xaml:
<Window x:Class="LargeItemsCollection.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:LargeItemsCollection"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:BigList/>
</Grid>
</Window>
MainWindow.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace LargeItemsCollection
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new BindingViewModel();
}
}
}