I have a ListView
in my window. The ListView
's default ItemsPanel
was replaced with WrapPanel
. I also have a DataTemplate
for it's ListViewItem
s. In Runtime, main window will not responding for some time because the ListView
have more than 700 (and keep increasing) ListViewItem
s (from data binding). Is there a way to keep the main window responsive?
OPTIONAL: When the ListView
is not ready, i want a text (or ProgressBar
if possible) show up over the ListView
and saying something like "Please Wait..." or maybe "Loading Items...".
XAML:
<ListView x:Name="MyListView" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling" HorizontalAlignment="Left" Height="577" VerticalAlignment="Top" Width="902" ScrollViewer.HorizontalScrollBarVisibility="Auto" Foreground="Black" Margin="10,10,0,0" ScrollViewer.CanContentScroll="True" BorderBrush="#FFC54B4B" BorderThickness="3" Background="White">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel MaxWidth="{Binding (FrameworkElement.ActualWidth),
RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
ItemWidth="{Binding (ListView.View).ItemWidth,
RelativeSource={RelativeSource AncestorType=ListView}}"
MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}"
ItemHeight="{Binding (ListView.View).ItemHeight,
RelativeSource={RelativeSource AncestorType=ListView}}" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
EDIT:
I tried this:
List<something> MyList = new List<something>();
ThreadPool.QueueUserWorkItem(_ =>
{
( Create MyList here...)
Dispatcher.BeginInvoke(new Action(() =>
{
MyListView.ItemsSource = MyList;
}));
});
Main window is still not responding until the ListView ready.
You use panel (WrapPanel) which cannot do UI virtualization (unlike VirtualizingStackPanel which is used in default ListView ItemPanel template). What that means is all your items are rendered, even those which are not visible at the moment. WPF does not have virtualizing wrap panel built-in, as far as I know, so you can try some free virtualizing wrap panels (example - http://virtualwrappanel.codeplex.com/), but I cannot say how good they are, I use version from Telerik which is not free. Another option is switch back to VirtualizingStackPanel. In addition to that, ensure that you load your items on non-UI thread (as mentioned in another answer).
If the UI thread is doing a Long-time operation it won't be able to process UI requests. This is also known as Not Responding. Use ThreadPool
like this:
private void operation_Click(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem(_ =>
{
var result = LongTimeOperation();//set the operation in another thread so that the UI thread is kept responding
//use the Dispatcher to "return" to the UI thread
Dispatcher.BeginInvoke(new Action(() =>
{
//Use result
}));
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With