0

Hello guys i am new to stackoverflow, sorry for mistakes in my post.

My question: I am binding a dataview to itemsControl when the data loads (binding actually) the UI Freezes. The data is too large, more then 600 rows, I want my data to bind one by one or all at once but smoothly.

I implemented the Nito Async.EX libraries but it didn't work.

private INotifyTaskCompletion<DataView> _studentlist;
Public INotifyTaskCompletion<DataView> StudentList
{
  get { return _studentlist; }
  set { SetProperty(ref _studentlist, value); }

}
private async Task Fill()
{
  StudentList = NotifyTaskCompletion.Create(GetData());
}

private async Task<DataView> GetData()
{
   Loading = true;
   await Task.Delay(100);

   DataTable StudentListTable = await DbContext.QueryT(SelectQuery);

   DataColumn DC = new DataColumn("DELETE", typeof(bool));
   DC.DefaultValue = false;
   StudentListTable.Columns.Add(DC);

   Loading = false;
   return StudentListTable.DefaultView;
}


References:
Prism for MVVM
Unity for prism
Nito Async.EX
Mahapps.Metro
Material Design Xaml toolkit

Any help would be appreciated.

Bojan B
  • 2,091
  • 4
  • 18
  • 26

2 Answers2

0

NotifyTaskCompletion will free up your UI while the data is loading, but not while it's binding.

The data is too large, more then 600 rows, I want my data to bind one by one or all at once but smoothly.

There's only one way to do this: virtualization.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
0

If your problem really is databinding to too many rows, UI Virtualization will work.

This is the easiest way to verify it: Replace the ScrollViewer and the ItemsControl with ListBox.

<ListBox ItemsSource="{Binding StudentList.Result}" Height="500" />

ListBox has UI Virtualization turned on by default. Don't forget to set height to fixed value, just for now.

If this helps, than the problem was really in DataBinding to too many rows. Check this answer to question "Virtualizing an ItemsControl?" to make it work with ItemsControl.

If this does not help, then the problem is somewhere else and we need to find out.


PS: In order to make UI Virtualization to work, VirtualizingStackPanel must be direct child of ScrollViewer in VisualTree. Your VisualTree looks something like this:

ScrollViewer
   ItemsControl
        StackPanel (Defined by ItemsControl.ItemsPanel)

You need to change it to:

ItemsControl
    ScrollViewer
          VirtualizingStackPanel (Defined by ItemsControl.ItemsPanel)

You can do it so by modifying ItemsControl.Template to include the ScrollViewer and by changing ItemsPanelTemplate to VirtualizingStackPanel. See the link above. There is also great tool to explore VisualTree in Visual Studio called Live Visual Tree

Community
  • 1
  • 1
Liero
  • 25,216
  • 29
  • 151
  • 297
  • It works fine with listbox the data is Virtualized of course of VirtualizationStackPanel. But the problem is my data template. I need VirtualizeWrapPanel instead of VirtualizationStackPanel .The code is too large to past here so please download from Google Drive Download =================================================================================================================https://drive.google.com/drive/folders/0B8OB-A4gGzqNME9VLWYwMFdNRVk?usp=sharing – Muhammad Shakeel Sep 14 '16 at 14:49
  • First of all, differentiate between `DataTemplate` and `ItemsPanelTemplate`. You set `DataTemplate` to `ItemsControl.ItemTemplate` property to define content of single item, and you set `ItemsPanelTemplate` to `ItemsControl.ItemTemplate` property to define layout of all properties. Second, WPF does not contain VirtualizingWrapPanel out of the box, but you can google some community libraries. Sometimes it is called also VirtualizingTilePanel. Just set it to `ListBox.ItemsPanel -> ItemsPanelTemplate -> VirtualizingWrapPanel resp VirtualizingTilePanel`. – Liero Sep 14 '16 at 15:19