ListView IsRefreshing doesn't stop

davidxf4davidxf4 ✭✭Member ✭✭
edited May 20 in Xamarin.Forms

Hi

I using a listview and at moment the finish charge, the loading spinner runs and doesn't stop, Here is my code:

 private bool isRefreshing;
 public bool IsRefreshing
        {
            get { return this.isRefreshing; }
            set { this.SetValue(ref this.isRefreshing, value); }
        }

public ICommand RefreshCommand
        {
            get
            {
                return new RelayCommand(Load);  // MvvmLightLibsStd10
            }
        }

private async void Load()
        {

                this.IsRefreshing = true;

        // Process

                this.IsRefreshing = false;

        }

My Code XAML

<ListView
       SelectionMode="None"
       IsRefreshing="{Binding IsRefreshing, Mode=OneWay}"
       IsPullToRefreshEnabled="True"
       RefreshCommand="{Binding RefreshCommand}"
       ItemsSource="{Binding Payments}">
       <ListView.ItemTemplate>
        .........
</ListView>

If I use this instruction it works correctly, but I think it is not right

private async void Load()
        {

             Device.BeginInvokeOnMainThread(() => {
                this.IsRefreshing = true;
            });

        // Process

             Device.BeginInvokeOnMainThread(() => {
                this.IsRefreshing = false;
            });

        }

Thanks.

Answers

  • FaizalSaidaliFaizalSaidali ✭✭✭ USMember ✭✭✭

    @davidxf4 Change your code to IsRefreshing="{Binding IsRefreshing, Mode=TwoWay}".
    Otherwise you just remove the mode. The IsRefreshing property have a default binding mode of TwoWay.

  • LucasZhangLucasZhang Xamurai Member, Xamarin Team Xamurai

    Refer to the following code

    public class MyViewModel: INotifyPropertyChanged
        {
            public ObservableCollection<Model> Payments { get; set; }
    
            private bool _isRefreshing = false;
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            public bool IsRefreshing
            {
                get { return _isRefreshing; }
                set
                {
                    _isRefreshing = value;
                    PropertyChanged(this, new PropertyChangedEventArgs("IsRefreshing"));
                }
            }
    
            public MyViewModel()
            {
                Payments = new ObservableCollection<xxx>() {
    
                    //...
    
                };
    
            }
    
            public ICommand RefreshCommand
            {
                get
                {
                    return new Command(async () =>
                    {
                        IsRefreshing = true;
    
                        await RefreshData;
    
                        IsRefreshing = false;
                    });
                }
            }
    
            private Task RefreshData => Task.Delay(5000);
        }
    

    And if you want to let listview refresh when it been first loaded.

    in contentPage

    MyViewModel ViewModel;
    
    public MainPage()
    {
     InitializeComponent();
    
     ViewModel = new MyViewModel();
    
     BindingContext = ViewModel;
    
    }
    
    protected override void OnAppearing()
    {
     base.OnAppearing();
    
     ViewModel.RefreshCommand.Execute(null);
    }
    
  • davidxf4davidxf4 ✭✭ Member ✭✭

    @LucasZhang said:
    Refer to the following code

    public class MyViewModel: INotifyPropertyChanged
        {
            public ObservableCollection<Model> Payments { get; set; }
    
            private bool _isRefreshing = false;
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            public bool IsRefreshing
            {
                get { return _isRefreshing; }
                set
                {
                    _isRefreshing = value;
                    PropertyChanged(this, new PropertyChangedEventArgs("IsRefreshing"));
                }
            }
    
            public MyViewModel()
            {
                Payments = new ObservableCollection<xxx>() {
    
                    //...
    
                };
    
            }
    
            public ICommand RefreshCommand
            {
                get
                {
                    return new Command(async () =>
                    {
                        IsRefreshing = true;
    
                        await RefreshData;
    
                        IsRefreshing = false;
                    });
                }
            }
    
            private Task RefreshData => Task.Delay(5000);
        }
    

    And if you want to let listview refresh when it been first loaded.

    in contentPage

    MyViewModel ViewModel;
    
    public MainPage()
    {
     InitializeComponent();
    
     ViewModel = new MyViewModel();
    
     BindingContext = ViewModel;
                           
    }
    
    protected override void OnAppearing()
    {
     base.OnAppearing();
    
     ViewModel.RefreshCommand.Execute(null);
    }
    

    @FaizalSaidali said:
    @davidxf4 Change your code to IsRefreshing="{Binding IsRefreshing, Mode=TwoWay}".
    Otherwise you just remove the mode. The IsRefreshing property have a default binding mode of TwoWay.

    Thanks for your help, however, it did not work

    IsRefreshing="{Binding IsRefreshing, Mode=TwoWay}"
    
  • davidxf4davidxf4 ✭✭ Member ✭✭

    @FaizalSaidali said:
    @davidxf4 Change your code to IsRefreshing="{Binding IsRefreshing, Mode=TwoWay}".
    Otherwise you just remove the mode. The IsRefreshing property have a default binding mode of TwoWay.

    Thanks for your help, however, it did not work

    IsRefreshing="{Binding IsRefreshing, Mode=TwoWay}"
    
    
  • davidxf4davidxf4 ✭✭ Member ✭✭

    @LucasZhang said:
    Refer to the following code

    public class MyViewModel: INotifyPropertyChanged
        {
            public ObservableCollection<Model> Payments { get; set; }
    
            private bool _isRefreshing = false;
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            public bool IsRefreshing
            {
                get { return _isRefreshing; }
                set
                {
                    _isRefreshing = value;
                    PropertyChanged(this, new PropertyChangedEventArgs("IsRefreshing"));
                }
            }
    
            public MyViewModel()
            {
                Payments = new ObservableCollection<xxx>() {
    
                    //...
    
                };
    
            }
    
            public ICommand RefreshCommand
            {
                get
                {
                    return new Command(async () =>
                    {
                        IsRefreshing = true;
    
                        await RefreshData;
    
                        IsRefreshing = false;
                    });
                }
            }
    
            private Task RefreshData => Task.Delay(5000);
        }
    

    And if you want to let listview refresh when it been first loaded.

    in contentPage

    MyViewModel ViewModel;
    
    public MainPage()
    {
     InitializeComponent();
    
     ViewModel = new MyViewModel();
    
     BindingContext = ViewModel;
                           
    }
    
    protected override void OnAppearing()
    {
     base.OnAppearing();
    
     ViewModel.RefreshCommand.Execute(null);
    }
    

    Thanks for your help, I use this class with INotifyPropertyChanged

    public class BaseViewModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    
            protected void SetValue<T>(ref T backingFiled, T value, [CallerMemberName] string propertyName = null)
            {
                if (EqualityComparer<T>.Default.Equals(backingFiled, value))
                {
                    return;
                }
    
                backingFiled = value;
                OnPropertyChanged(propertyName);
            }
        }
    
    public class PaymentViewModel : BaseViewModel
    {
    private bool isRefreshing;
    public bool IsRefreshing
            {
                get { return this.isRefreshing; }
                set { this.SetValue(ref this.isRefreshing, value); }
            }
    ........
    }
    

    my app.cs

     public App ()
    {
         InitializeComponent();
    
              if (Settings.IsRemember)
                {
                    var user = JsonConvert.DeserializeObject<User>(Settings.User);
                    var mainViewModel = MainViewModel.GetInstanceSingleton();
                    mainViewModel.User = user;
                    mainViewModel.InfoPage = new InfoPageViewModel();
                    mainViewModel.PaymentPage = new PaymentViewModel();
                    this.MainPage = new BrittanyTabbedPage();
                    return;
                }
    
                MainPage = new LoginPage();
    }
    
  • LucasZhangLucasZhang Xamurai Member, Xamarin Team Xamurai

    @davidxf4 Glad my answer is helpful. Don't forget to mark as Accepted Answer and Like any posts that help you.

Sign In or Register to comment.