与Listbox绑定数据表时,C#WPF UI冻结

时间:2017-03-21 10:29:51

标签: c# wpf multithreading

嗨我正在使用DataTable与Listbox绑定数据 DataTable行数= 1000+,我必须加载所有行。

和我绑定时

// Inside BackgroundThread
DataTable table = GetDataFromServer(); // Get Data (DataTable row count = 1000+)
this.Dispatcher.Invoke(new Action(() =>
{
      FilteredList.DataContext = table ; // UI Hangs Progress bar freeze around 20-30+ seconds

}), DispatcherPriority.Background);

XML代码

 <Grid Grid.Row="0" x:Name="gridFilteredList" Visibility="Collapsed">
            <ListView Style="{DynamicResource MyListView}" Grid.Row="0" AllowDrop="True" x:Name="FilteredList"  
              IsSynchronizedWithCurrentItem="False" ItemsSource="{Binding Mode=OneWay}"
              BorderThickness="0" BorderBrush="Black"  ScrollViewer.ScrollChanged="syncList_ScrollChanged"
              ItemContainerStyle="{StaticResource BorderedListViewItemStyle}" SelectedItem="{x:Null}"
              Background="{DynamicResource DefaultMSBackgroundColor}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
              HorizontalContentAlignment="Stretch" ScrollViewer.CanContentScroll="False" Focusable="True" SelectionChanged="syncList_SelectionChanged" SelectionMode="Single" MouseMove="syncList_MouseMove"
                  MouseEnter="syncList_MouseEnter"
             MouseLeave="syncList_MouseLeave">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Grid x:Name="FileItemGrid" Margin="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Cursor="Hand">
                            <Grid Margin="0 10 10 10" Height="35" >
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="40"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <Image Grid.Column="0" Cursor="Hand"  Source="{Binding Path=imagestring, Mode=OneWay}" VerticalAlignment="Center"  Margin="5,0" HorizontalAlignment="Center" Style="{StaticResource Image32StyleNearestNeighbor}" />
                                <Grid Grid.Column="1">
                                    <Grid.RowDefinitions>
                                        <RowDefinition />
                                        <RowDefinition />
                                    </Grid.RowDefinitions>
                                    <Grid Grid.Row="0" >
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="Auto" />
                                        </Grid.ColumnDefinitions>
                                        <TextBlock Grid.Column="0" Cursor="Hand" Foreground="#FF333333" TextTrimming="CharacterEllipsis" TextWrapping="NoWrap" VerticalAlignment="Center" Text="{Binding Path=name, Mode=OneTime}" />
                                        <TextBlock Grid.Column="1" Cursor="Hand" Foreground="#FF333333" TextTrimming="CharacterEllipsis" TextWrapping="NoWrap" VerticalAlignment="Center" Text="{Binding Path=size, Mode=OneTime}" HorizontalAlignment="Right" />
                                    </Grid>
                                    <TextBlock Grid.Row="1"  FontSize="11"  TextTrimming="CharacterEllipsis" VerticalAlignment="Center" >
                                    <Run Text="{Binding Path=formattedtime, Mode=OneTime}" Foreground="#FFB3B3B3"/>
                                    <Run Text="-"/>
                                    <Run Text="{Binding Path=activity, Mode=OneTime}" Foreground="{Binding Path=StatusLabelColour, Mode=OneTime}"/>
                                    </TextBlock>
                                </Grid>
                                <Grid Grid.Column="1" Margin="5 0 0 0" HorizontalAlignment="Right" VerticalAlignment="Bottom">
                                    <Grid Visibility="{Binding Path=DeleteImageVisible, Mode=OneWay}" ToolTip="Click to recover file" Name="SyncDelete" 
                                           Cursor="Hand" MouseLeftButtonDown="SyncDelete_MouseLeftButtonDown" Style="{DynamicResource GridWithBackground}">
                                        <Image x:Name="imgDelete" SnapsToDevicePixels="True" Source="pack://application:,,,/Resources/UserControl/SyncSummary_Delete.png" 
                                                Style="{StaticResource Image16StyleHighQuality}"/>
                                    </Grid>
                                    <Image Name="errorImage" VerticalAlignment="Center" Cursor="Hand" HorizontalAlignment="Center" Style="{StaticResource Image16StyleHighQuality}" 
                                           Source="{Binding Path=errorStringImage, Mode=OneWay}" ToolTip="{Binding Path=errorStringToolTip, Mode=OneWay}" ToolTipService.ShowDuration="50000" UseLayoutRounding="True" />
                                </Grid>
                                <Button Grid.Column="1" x:Name="btnShare" Content="Share" Click="btnShare_Click" Margin="0,0,10,0" >
                                    <Button.Style>
                                        <Style TargetType="Button">
                                            <Setter Property="Foreground" Value="White" />
                                            <Setter Property="Height" Value="30" />
                                            <Setter Property="Padding" Value="10,0,10,0" />
                                            <Setter Property="Cursor" Value="Hand" />
                                            <Setter Property="BorderBrush" Value="Black" />
                                            <Setter Property="Background" Value="{DynamicResource DefaultMSForegroundColor}" />
                                            <Setter Property="VerticalContentAlignment" Value="Center" />
                                            <Setter Property="HorizontalContentAlignment" Value="Center" />
                                            <Setter Property="FontWeight" Value="Bold" />
                                            <Setter Property="HorizontalAlignment" Value="Right" />
                                            <Setter Property="Visibility" Value="Collapsed" />
                                            <Style.Triggers>
                                                <Trigger Property="IsMouseOver" Value="True">
                                                    <Setter Property="Foreground" Value="Black" />
                                                </Trigger>
                                                <MultiDataTrigger>
                                                    <MultiDataTrigger.Conditions>
                                                        <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListViewItem}},Path=IsMouseOver, Mode=OneWay}"
                                                               Value="True" />
                                                        <Condition Binding="{Binding Path=ShareBtnVisible, Mode=OneWay}"
                                                               Value="Visible" />
                                                    </MultiDataTrigger.Conditions>
                                                    <MultiDataTrigger.Setters>
                                                        <Setter Property="Visibility" Value="Visible" />
                                                    </MultiDataTrigger.Setters>
                                                </MultiDataTrigger>
                                            </Style.Triggers>
                                        </Style>
                                    </Button.Style>
                                </Button>
                            </Grid>
                        </Grid>
                    </DataTemplate>

                </ListView.ItemTemplate>
            </ListView>
        </Grid>

我应该使用ObservationCollection或任何其他设计模式来解决冻结问题吗?

2 个答案:

答案 0 :(得分:3)

您正在将ScrollViewer.CanContentScroll的{​​{1}}附加属性设置为ListView,这有效地禁用了内置的UI虚拟化,这会对性能产生负面影响。

如果您关心渲染和滚动性能,请不要将此属性设置为false

答案 1 :(得分:2)

将您的代码放在Task(自己的主题)中,您的用户界面将不再冻结。在UI线程中调用长时间运行的操作时,你总会遇到这个问题。