我无法获得此ItemsControl
进行正确的虚拟化。调试表明,集合可以快速初始化,但是所有项目都被添加到控件中,而不是子集(我只是将TracePoint放入组成项目的TextBox_Initialize event in the
UserControl`中)。
注意:我看过其他类似的问题,但是无法用这些答案解决此问题。
ViewModel:
public class ImportInformationViewModel : CommandViewModel
{
public ImportInformationViewModel()
{
this.PropertyChanged += ImportInformationViewModel_PropertyChanged;
}
private ObservableCollection<SingleTransactionViewModel> mTransactions;
public ReadOnlyObservableCollection<SingleTransactionViewModel> Transactions
{
get
{
if (mTransactions == null)
mTransactions = new ObservableCollection<SingleTransactionViewModel>();
var filtered = mTransactions.Where(trans => !trans.IgnoreTransaction)
.OrderBy(trans => trans.DateStamp)
.ThenBy(trans => trans.TransactionName)
.ThenBy(trans => trans.TransactionDetail);
return new ReadOnlyObservableCollection<SingleTransactionViewModel>(new ObservableCollection<SingleTransactionViewModel>(filtered));
}
}
private void ImportInformationViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "TransactionFileName")
{
if (File.Exists(mTransactionFileName))
{
mTransactions.Clear();
// Process File (Not Shown)
mTransactions.Add(new SingleTransactionViewModel()
{
DateStamp = date,
TransactionDetail = someText;
});
}
}
if (e.PropertyName != "Transactions")
NotifyPropertyChanged("Transactions");
}
}
SingleTransactionViewModel
只是另一个实现INotifyPropertyChanged
的类。没什么特别的。
这是包含ItemsControl
<UserControl x:Class="ImportInformationView">
<UserControl.Resources>
<CollectionViewSource x:Key="TransactionsData" Source="{Binding Transactions}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="YearAndMonth" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
<BooleanToVisibilityConverter x:Key="booleanToVisibility" />
</UserControl.Resources>
<ItemsControl ItemsSource="{Binding Source={StaticResource TransactionsData}}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
ScrollViewer.CanContentScroll="True"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
MinHeight="20">
<ItemsControl.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<GroupBox Padding="5" Margin="2,5">
<GroupBox.Header>
<Border Background="Black"
CornerRadius="4">
<TextBlock Text="{Binding Name}" />
</Border>
</GroupBox.Header>
<ItemsPresenter />
</GroupBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ItemsControl.GroupStyle>
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer CanContentScroll="True">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid IsItemsHost="True" Columns="2" Grid.IsSharedSizeScope="True" VirtualizingStackPanel.IsVirtualizing="True" />
<!--<VirtualizingStackPanel IsItemsHost="True" />-->
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<views:SingleTransactionView Margin="4,6" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</UserControl>
我将SingleTransactionView
简化为非常简单的内容:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="ExpanderColumn" />
<ColumnDefinition Width="*" SharedSizeGroup="TransactionNameColumn" />
<ColumnDefinition Width="Auto" SharedSizeGroup="DateColumn" />
<ColumnDefinition Width="Auto" SharedSizeGroup="OptionsColumn" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="1"
Grid.Row="0"
Initialized="TextBlock_Initialized"
Text="{Binding TransactionName}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
FontWeight="Bold"
Margin="4"/>
</Grid>
答案 0 :(得分:1)
这可能是由于您使用了分组。默认情况下,启用分组可有效关闭虚拟化。但是,从.NET 4.5开始,您应该能够通过VirtualizingPanel.IsVirtualizingWhenGrouping
属性来重新获得此功能。
摘录自this blog post,有关.NET 4.5中WPF的增强功能:
在WPF 4.0中,对显示的集合进行分组后,您失去了虚拟化功能。我重复一遍:分组= WPF 4.0中没有虚拟化。这仍然是WPF 4.5的默认行为,但是您可以通过使用
IsVirtualizingWhenGrouping
附加属性来打开虚拟化。VirtualizingPanel
类。完成此操作后,您将从所有已经描述的虚拟化优势中受益。以下是通过XAML启用它的方法:
<ListBox ItemsSource="{Binding Persons}" ItemTemplate="{StaticResource PersonDataTemplate}" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.IsVirtualizingWhenGrouping="True"> <ListBox.GroupStyle> <GroupStyle HeaderTemplate="{StaticResource GroupHeaderTemplate}" /> </ListBox.GroupStyle> </ListBox>
在其他与虚拟化相关的属性旁边设置VirtualizingPanel.IsVirtualizingWhenGrouping="True"
之类的声音应该会为您提供所需的行为。+