C # WPF UI freezes when data binding to Listbox
hi I am using DataTable for data binding with List of Rows DataTable = 1000+ and I need to load the whole row.
and when I tie
// 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 Code
<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>
Should I use ObservationCollection or any other design pattern to solve the freeze problem?
You are setting a property ScrollViewer.CanContentScroll
from ListView
to false
, which effectively disables native UI virtualization, which negatively affects performance.
Don't set this property to false
if you need rendering and scrolling performance.
Put your code on Task
(native thread) and your UI won't freeze anymore. You will always have this problem when calling long operations on the UI thread.