【发布时间】:2010-12-09 20:21:50
【问题描述】:
这里是这样的场景,我有一个清除 ObservableCollection、运行查询并使用查询结果重新填充集合的操作。此集合由列表框数据绑定。这是踢球者,500 个查询结果会导致一些严重的更新时间,这会阻止用户界面被认为“太长”(实际上在大多数系统上是 0.5-2 秒)无论哪种方式,我都知道查询足够快,就像添加元素一样,所以我将其缩小到表示层。
做一些测试,如果我从列表框中删除项目模板,我会获得明显更好的性能(duh),但不会好到它甚至可以满足传达给我的期望。我将绑定更新为一种适用的方式,我将虚拟化模式更改为回收,并确保我使用的是静态资源,以上都没有对重绘产生明显影响。我想知道是否有人知道如何提高填充大量项目的列表框的性能?
<ListBox x:Name="listBox" Grid.Row="1" Grid.ColumnSpan="5" ItemsSource="{Binding SerialResults}" ItemTemplate="{StaticResource UnitHistoryTemplate}" BorderThickness="2" Grid.IsSharedSizeScope="True" VirtualizingStackPanel.VirtualizationMode="Recycling">
<DataTemplate x:Key="UnitHistoryTemplate">
<DataTemplate.Resources>
<DataTemplate x:Key="UnitFailureItemTemplate">
<Grid>
<TextBlock Margin="4,0,4,0" TextWrapping="Wrap" Text="{Binding}" Foreground="Red"/>
</Grid>
</DataTemplate>
</DataTemplate.Resources>
<Grid d:DesignWidth="580" d:DesignHeight="30" Background="#00000000">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="load"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="run"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="ser"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="mot"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="result"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="Load" Text="{Binding Load.LoadNumber, Mode=OneTime}" Margin="4,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" d:LayoutOverrides="HorizontalAlignment"/>
<TextBlock x:Name="Run" Text="{Binding Run.RunNumber, Mode=OneTime}" Margin="4,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" d:LayoutOverrides="HorizontalAlignment" Grid.Column="1"/>
<TextBlock x:Name="Serial" Text="{Binding Unit.SerialNumber, Mode=OneTime}" Margin="4,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" d:LayoutOverrides="HorizontalAlignment" Grid.Column="2"/>
<TextBlock x:Name="Mot" Text="{Binding Unit.MotString, Mode=OneTime}" Margin="4,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" d:LayoutOverrides="HorizontalAlignment" Grid.Column="3"/>
<TextBlock x:Name="Result" Text="{Binding Run.Result, Mode=OneTime}" Margin="4,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Column="4" d:LayoutOverrides="HorizontalAlignment, GridBox"/>
<ItemsControl ItemsSource="{Binding Unit.Failed, Mode=OneTime}" ItemTemplate="{StaticResource UnitFailureItemTemplate}" HorizontalAlignment="Left" Margin="4,0,0,0" Grid.Column="5">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Run.Result, Mode=OneTime}" Value="Aborted">
<DataTrigger.Setters>
<Setter TargetName="Result" Property="Foreground" Value="Red"/>
</DataTrigger.Setters>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
由于它在下面被问过几次,不,这不是我的可观察集合...我正在通过执行一批更新并将项目源重新分配给新实例来抑制事件。
public async void FindUnitHistory()
{
if (IsCaching)
{
return;
}
else if (_serialSearch.Length <= MIN_SEARCH_LENGTH)
{
SerialResults.Clear();
return;
}
var newData = new ObservableCollection<UnitHistory>();
await TaskEx.Run(() =>
{
var results = from load in cache.LoadData.AsParallel()
from run in load.Runs
from unit in run.Units
where unit.SerialNumber.StartsWith(_serialSearch)
orderby run.RunNumber ascending
orderby load.LoadNumber descending
select new UnitHistory(load, run, unit);
foreach (var p in results)
{
newData.Add(p);
}
});
SerialResults = newData;
}
【问题讨论】:
标签: c# wpf performance data-binding