GridView Spinner doesn't hide away (IsBusy)

23 posts, 2 answers
  1. Vitor
    Vitor avatar
    53 posts
    Member since:
    Mar 2016

    Posted 18 Mar Link to this post

    Hello Telerik,

     

    I have an issue when I try using your IsBusy property inside a grid.

    Happens that the panel won't disappear. I tried using several of those "Loaded" events to make it happen manually (grid.IsBusy = false;), but then it won't even show at all.

    I am using virtualization and infinite scrolling in my grid.

    I just need a solution to hide the spinner when the data finish loading.

     

    here is my code:

     

    MainWindow.xaml

    <Window x:Class="TelerikVirtualization.MainWindow"
                    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
                     
                    Title="MainWindow" Height="900" Width="700" >
     
        <Window.Resources>
            <Style x:Key="VitorStyle" TargetType="telerik:RadGridView" >
                <Setter Property="AutoGenerateColumns" Value="False"></Setter>
                <Setter Property="FilteringMode" Value="FilterRow"></Setter>
            </Style>
        </Window.Resources>
        <Grid>
                <Grid.Resources>
                <DataTemplate x:Key="RowDetailsTemplate">
                    <telerik:RadGridView Name="playersGrid"  Style="{StaticResource VitorStyle}" IsBusy="True"
                                         ItemsSource="{Binding Children}" >
                        <telerik:RadGridView.ControlPanelItems>
                            <telerik:ControlPanelItem ButtonTooltip="Column chooser">
                                <telerik:ControlPanelItem.Content>
                                    <ListBox ItemsSource="{Binding Columns}" BorderThickness="0">
                                        <ListBox.ItemTemplate>
                                            <DataTemplate>
                                                <CheckBox Content="{Binding Header, Mode=OneWay}" IsChecked="{Binding IsVisible, Mode=TwoWay}" />
                                            </DataTemplate>
                                        </ListBox.ItemTemplate>
                                    </ListBox>
                                </telerik:ControlPanelItem.Content>
                            </telerik:ControlPanelItem>
                        </telerik:RadGridView.ControlPanelItems>
                        <telerik:RadGridView.Columns>
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding ID}"/>
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding Name}"/>
                            <telerik:GridViewDataColumn DataMemberBinding="{Binding ParentID}"/>
                        </telerik:RadGridView.Columns>
     
                         
                    </telerik:RadGridView>
                </DataTemplate>
            </Grid.Resources>
            <telerik:RadGridView Name="RadGridView"  ItemsSource="{Binding View}" Style="{StaticResource VitorStyle}" IsBusy="True"
                                 RowDetailsTemplate="{StaticResource RowDetailsTemplate}" AutoGenerateColumns="False">
                <telerik:RadGridView.Columns>
                    <telerik:GridViewToggleRowDetailsColumn/>
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding ID}"/>
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding Name}"/>
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding UnitPrice}" Header="UnitPrice" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding Date}"
                                                Header="Date"
                                                DataFormatString="{}{0:dd/MM/yyyy}"/>
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding Discontinued}"/>
                </telerik:RadGridView.Columns>
     
                <telerik:RadGridView.ControlPanelItems>
                    <telerik:ControlPanelItem ButtonTooltip="Column chooser">
                        <telerik:ControlPanelItem.Content>
                            <ListBox ItemsSource="{Binding Columns}" BorderThickness="0">
                                <ListBox.ItemTemplate>
                                    <DataTemplate>
                                        <CheckBox Content="{Binding Header, Mode=OneWay}" IsChecked="{Binding IsVisible, Mode=TwoWay}" />
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                            </ListBox>
                        </telerik:ControlPanelItem.Content>
                    </telerik:ControlPanelItem>
                </telerik:RadGridView.ControlPanelItems>
     
            </telerik:RadGridView>
        </Grid>
    </Window>

    MainWindow.xaml.cs

    using System.ComponentModel;
    using System.Windows;
    namespace TelerikVirtualization
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            BackgroundWorker worker = new BackgroundWorker();
            public MainWindow()
            {
                InitializeComponent();
                DataContext = new ViewModel();
            }
    }

    ViewModel.cs  *(install Fody.PropertyChanged nugget to make have it compiling)

    using PropertyChanged;
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using Telerik.Windows.Data;
    using System.Linq;
    using System.Collections;
     
    namespace TelerikVirtualization
    {
        [ImplementPropertyChanged]*
        public class ViewModel
        {
            public VirtualQueryableCollectionView View { get; set; }
            Controller controller;
            public ViewModel()
            {
                controller = new Controller();
                View = new VirtualQueryableCollectionView(controller.GetList()) { LoadSize = 10 };
            }
        
    }

    Controller.cs

    using System;
    using System.Linq;
     
    namespace TelerikVirtualization
    {
        public class Controller
        {
            public IQueryable GetList()
            {
                DataClasses1DataContext context = new DataClasses1DataContext();
                var result = from x in context.MyTables
                         select new MyTableEntity() {
                             Date = x.Date.GetValueOrDefault(DateTime.Now),
                             Name = x.Name,
                             UnitPrice = x.UnitPrice.GetValueOrDefault(0),
                             id = x.ID,
                             Discontinued = x.Discontinued,
                             Children = (from y in context.MyChildTables
                                         where y.ParentID == x.ID
                                         select new MyChildTableEntity { ID = y.ID, Name = y.Name, ParentID = y.ParentID })
                         };
                return result;
            }
        }
     
        public class MyTableEntity
        {
            public int id { get; set; }
            public string Name { get; set; }
            public decimal UnitPrice { get; set; }
            public DateTime Date { get; set; }
            public object Children { get; set; }
            public bool ? Discontinued { get; set; }
        }
        public class MyChildTableEntity
        {
            public int ID { get; set; }
            public string Name { get; set; }
            public int ? ParentID { get; set; }
     
        
    }

     

     

    Thank you.

     

     

     

     

     

     

     

     

     

     

  2. Dilyan Traykov
    Admin
    Dilyan Traykov avatar
    371 posts

    Posted 22 Mar Link to this post

    Hello Vitor,

    The correct approach in this scenario would be to set RadGridView's IsBusy property to True and then return it to False in the GridView's DataLoaded event.

    public MainWindow()
            {
                InitializeComponent();
                DataContext = new ViewModel();
                this.RadGridView.DataLoaded += RadGridView_DataLoaded;
            }
     
            private void RadGridView_DataLoaded(object sender, EventArgs e)
            {
                this.RadGridView.IsBusy = false;
            }

    Please let me know if this answers your question. Don't hesitate to contact us again should any further questions or concerns arise.

    Regards,
    Dilyan Traykov
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  3. UI for WPF is Visual Studio 2017 Ready
  4. Vitor
    Vitor avatar
    53 posts
    Member since:
    Mar 2016

    Posted 22 Mar in reply to Dilyan Traykov Link to this post

    Hi Dilyan.

    If I use that code, the spinner won't show at all.

    please try to reproduce my scenario on your side, you have my code

    thank you

  5. Dilyan Traykov
    Admin
    Dilyan Traykov avatar
    371 posts

    Posted 22 Mar Link to this post

    Hello Vitor,

    I did try to reproduce your scenario, but the behavior I get is expected. The reason the BusyIndicator is not shown is that RadGridView loads the items instantaneously. To simulate the loading of items, I've added a 2-second delay. You can see that once the items are actually loaded, the indicator is hidden.

    I'm attaching a modified version of your project to my reply. Please let me know if I've missed something important.

    Regards,
    Dilyan Traykov
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  6. Vitor
    Vitor avatar
    53 posts
    Member since:
    Mar 2016

    Posted 22 Mar in reply to Dilyan Traykov Link to this post

    but if I modify your sample and remove that timer, the list will take some time to load (cos its 1 million rows), but wont show the spinner...

    can you try that scenario?

    thank you

  7. Answer
    Dilyan Traykov
    Admin
    Dilyan Traykov avatar
    371 posts

    Posted 23 Mar Link to this post

    Hello Vitor,

    I've modified my sample project and attached it to my reply. It makes use of the ItemsLoading and ItemsLoaded events of the VirtualQueryableCollectionView and displays the IsBusyIndicator when necessary. Please note that with this approach, the IsBusyIndicator will be shown each time the ItemsLoading is called.

    Could you please have a look at the attached project and let me know if this approach would work for you?
    I would also like to ask - is there a specific reason you're using a VirtualQueryableCollectionView? If that is not the case, maybe I can offer another solution based on your specific requirements.

    Regards,
    Dilyan Traykov
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  8. Vitor
    Vitor avatar
    53 posts
    Member since:
    Mar 2016

    Posted 29 Mar in reply to Dilyan Traykov Link to this post

    Yes there is:

    I followed your documentations regarding an endless scrolling (virtualization load) method. because your pagination via RadPageControl is broken when we apply the filter on the grid.

    the endless scrolling works really fine with the filter and everything

     

    I will give your solution a try and return in a minute

  9. Vitor
    Vitor avatar
    53 posts
    Member since:
    Mar 2016

    Posted 29 Mar in reply to Vitor Link to this post

    It is WORKING!!!

     

    Thank you once more

  10. Vitor
    Vitor avatar
    53 posts
    Member since:
    Mar 2016

    Posted 30 Mar Link to this post

    There is just one detail that is missing:

    the spinner doesn't "spin"

    it only shows there, without animation.

    what's wrong?

  11. Stefan X1
    Admin
    Stefan X1 avatar
    523 posts

    Posted 31 Mar Link to this post

    Hi Vitor,

    Such behavior would be expected, as both the animation and the data loading are executed on the UI thread. You need to move the time consuming operation on a separate thread. This can be achieved by using a Background Worker. You may also find the How to use WPF Background Worker StackOverflow thread useful.

    Hope this helps.

    Regards,
    Stefan X1
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  12. Vitor
    Vitor avatar
    53 posts
    Member since:
    Mar 2016

    Posted 01 Apr in reply to Stefan X1 Link to this post

    Hi Stefan

    The logic of the backgroundworker is reasonable to solve this problem. but it won't match with Dilyan Traykov last solution.

    because it needs to use the fully initialized View (list) and set the View_ItemsLoading and View_ItemsLoaded events upon it

    when I use the BackgroundWorker, it will simply throw me a null exception

  13. Dilyan Traykov
    Admin
    Dilyan Traykov avatar
    371 posts

    Posted 06 Apr Link to this post

    Hello Vitor,

    I will need a little more time to search for a solution for your scenario, but I will get back to you as soon as possible.

    Regards,
    Dilyan Traykov
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  14. Vitor
    Vitor avatar
    53 posts
    Member since:
    Mar 2016

    Posted 06 Apr in reply to Dilyan Traykov Link to this post

    Thank you very much Dilyan.

    I will be looking forward to hear from you

  15. Answer
    Dilyan Traykov
    Admin
    Dilyan Traykov avatar
    371 posts

    Posted 06 Apr Link to this post

    Hello Vitor,

    Thank you for your patience.

    Another approach I can suggest is to wrap your RadGridView in a RadBusyIndicator with a DisplayAfter property set to 0​ and then set its (rather than RadGridView's) IsBusy property in the ItemsLoading and ItemsLoaded events:

    <telerik:RadBusyIndicator Name="busyIndicator" IsBusy="True" DisplayAfter="0">
        <telerik:RadGridView Name="RadGridView" />
    </telerik:RadBusyIndicator>
    private void View_ItemsLoaded(object sender, VirtualQueryableCollectionViewItemsLoadedEventArgs e)
    {
        this.busyIndicator.IsBusy = false;
    }
     
    private void View_ItemsLoading(object sender, VirtualQueryableCollectionViewItemsLoadingEventArgs e)
    {
        this.busyIndicator.IsBusy = true;
    }

    Please let me know if you're satisfied with the result from this approach.

    Regards,
    Dilyan Traykov
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  16. Vitor
    Vitor avatar
    53 posts
    Member since:
    Mar 2016

    Posted 06 Apr in reply to Dilyan Traykov Link to this post

    FLAWLESS!

    Thank you very much!

  17. Vitor
    Vitor avatar
    53 posts
    Member since:
    Mar 2016

    Posted 06 Apr in reply to Vitor Link to this post

    I must retract what I have just said.

    The solution (actually both of them) fails when grouping.

    But it will still do for now. But please verify that further on...

    I might need to come back to this ticket later

  18. Dilyan Traykov
    Admin
    Dilyan Traykov avatar
    371 posts

    Posted 06 Apr Link to this post

    Hello Vitor,

    In order to group the items correctly, the VirtualQueryableCollectionView needs to load all the items beforehand and thus the ItemsLoading and ItemsLoaded events do not get fired.

    Please let me know if this clarifies things for you.

    Regards,
    Dilyan Traykov
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  19. Vitor
    Vitor avatar
    53 posts
    Member since:
    Mar 2016

    Posted 07 Apr in reply to Dilyan Traykov Link to this post

    Hey Dilyan,

    Yes it does. And it also explains why the performance is not the best when grouping...

    So there is no way of using a IsBusy indicator for the case?

    I tried handling the Grouping and Grouped events, for no use

  20. Dilyan Traykov
    Admin
    Dilyan Traykov avatar
    371 posts

    Posted 07 Apr Link to this post

    Hello Vitor,

    If you want to display the BusyIndicator when grouping and expanding the groups, you can use the following event handlers, which seem to be working fine at my end:

    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel();
        var view = (this.DataContext as ViewModel).View;
        view.ItemsLoading += View_ItemsLoading;
        view.ItemsLoaded += View_ItemsLoaded;
        this.RadGridView.Grouping += RadGridView_Grouping;
        this.RadGridView.Grouped += RadGridView_Grouped;
        this.RadGridView.GroupRowIsExpandedChanging += RadGridView_GroupRowIsExpandedChanging;
        this.RadGridView.GroupRowIsExpandedChanged += RadGridView_GroupRowIsExpandedChanged;
    }
     
    private void RadGridView_GroupRowIsExpandedChanged(object sender, Telerik.Windows.Controls.GridView.GroupRowEventArgs e)
    {
        this.busyIndicator.IsBusy = false;
    }
     
    private void RadGridView_GroupRowIsExpandedChanging(object sender, Telerik.Windows.Controls.GridView.GroupRowCancelEventArgs e)
    {
        this.busyIndicator.IsBusy = true;
    }
     
    private void RadGridView_Grouped(object sender, GridViewGroupedEventArgs e)
    {
        this.busyIndicator.IsBusy = false;
    }
     
    private void RadGridView_Grouping(object sender, GridViewGroupingEventArgs e)
    {
        this.busyIndicator.IsBusy = true;
    }
     
    private void View_ItemsLoaded(object sender, VirtualQueryableCollectionViewItemsLoadedEventArgs e)
    {
        this.busyIndicator.IsBusy = false;
    }
     
    private void View_ItemsLoading(object sender, VirtualQueryableCollectionViewItemsLoadingEventArgs e)
    {
        this.busyIndicator.IsBusy = true;
    }

    I've attached a modified version of my sample project to demonstrate this. Could you verify that you're using the same approach? 

    Regards,
    Dilyan Traykov
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  21. Vitor
    Vitor avatar
    53 posts
    Member since:
    Mar 2016

    Posted 12 Apr in reply to Dilyan Traykov Link to this post

    Hello Dilyan.

    I wish I could give you good news, but I used your sample and I couldn't get it to run.

    but as I noticed it approaches a slight different scenario, I decided to change is slightly to run it and get closer to my scenario:

    Here is what I changed:

    Controller.cs

    public IQueryable GetList()
    {
        var context = new DataClasses1DataContext();
        var result = context.MyTables;
        return result.AsQueryable();
    }

    MainWindow.xaml:

    <Window x:Class="TestRadGridView.MainWindow"
            xmlns:my="clr-namespace:TestRadGridView"
            Title="MainWindow" Height="700" Width="700">
        <Window.Resources>
            <Style x:Key="VitorStyle" TargetType="telerik:RadGridView" >
                <Setter Property="AutoGenerateColumns" Value="False"></Setter>
                <Setter Property="FilteringMode" Value="FilterRow"></Setter>
            </Style>
        </Window.Resources>
        <Grid>
            <telerik:RadBusyIndicator Name="busyIndicator" IsBusy="True" DisplayAfter="0">
                <telerik:RadGridView Name="RadGridView" ItemsSource="{Binding View}"
                                 AutoGenerateColumns="True">
                </telerik:RadGridView>
            </telerik:RadBusyIndicator>
        </Grid>
    </Window>

    And I added a Lint to SQL (dbml) file containing only one table (1 million rows on it. each with a random name and some random columns)

     

    This is it. And the grouping won't show the Spinner.

     

     

     

  22. Dilyan Traykov
    Admin
    Dilyan Traykov avatar
    371 posts

    Posted 14 Apr Link to this post

    Hello Vitor,

    I'm reattaching the modified project. At my end, it successfully displays the BusyIndicator once I group the items. Could you please have a look and let me know how this goes at your end?

    Regards,
    Dilyan Traykov
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  23. Vitor
    Vitor avatar
    53 posts
    Member since:
    Mar 2016

    Posted 14 Apr in reply to Dilyan Traykov Link to this post

    sorry but your sample doesn't reflect my scenario.

    My last post shows how to do so.

    - linq to sql

    - 1 million rows

  24. Dilyan Traykov
    Admin
    Dilyan Traykov avatar
    371 posts

    Posted 18 Apr Link to this post

    Hello Vitor,

    I have modified my project accordingly, but everything is still working as expected. Could you please modify the attached project or maybe send over a sample project of your own that demonstrates the behavior you're observing at your end?

    Thank you in advance for your cooperation on the matter.

    Regards,
    Dilyan Traykov
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
Back to Top
UI for WPF is Visual Studio 2017 Ready