Page with activityindicator and binding

AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

Hi my friends.
I've a very simple page (a button and an activityindicator in a stacklayout).
I try to use binding to activate / disactivate activityindicator using the notification class I've written with INotifyPropertyChanged.
When I press the button I would like to have the activityindicator visible and running . The code in the buttonclick event runs (it's an ftp... I would like to do it async but for now I have not succeeded), the "bind" properties (Visible and Running of Notification class) seems to change status, but activityindicator does not appear.
I don't know if it's a binding problem, a layout problem, o what else.
Can anyone help me?

This is the page

using System;
using Xamarin.Forms;
using FlagFtp;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace Geco
{
public class PageFtp: ContentPage
{
private Notification _notification = new Notification ();
public PageFtp ()
{
this.Title = "Carico database";

        var stacklayout = new StackLayout ();
        stacklayout.HorizontalOptions = LayoutOptions.Center;
        stacklayout.VerticalOptions = LayoutOptions.Center;

        var activityIndicator = new ActivityIndicator ();
        activityIndicator.IsEnabled = true;
        activityIndicator.SetBinding (ActivityIndicator.IsVisibleProperty, "Visible");
        activityIndicator.SetBinding (ActivityIndicator.IsRunningProperty, "Running");
        activityIndicator.BindingContext = _notification;

        bool okFtp = true;
        string errorFtp = "";

        // Verifico se ho il database
        var filename = DependencyService.Get<IFiles> ().GetFileName (App.DB_FILENAME);
        #if DEBUG
        DependencyService.Get<IFiles>().Delete(filename);
        #endif

        var buttonRetry = new Button ();
        buttonRetry.Text = "Procedere con il carico del database";
        buttonRetry.Clicked += (object sender, EventArgs e) =>{
            okFtp = ftp (filename, ref errorFtp);
            if(okFtp)
                DependencyService.Get<IOpenActivity>().OpenActivity(App.EnumForms.Login);
            else{
                DisplayAlert("Errore",errorFtp,"OK");
            }
        };

        stacklayout.Children.Add (buttonRetry);
        stacklayout.Children.Add (activityIndicator);
        this.Content = stacklayout;

    }


    private bool ftp(string filename, ref string error) {
        System.Net.NetworkCredential credentials = new System.Net.NetworkCredential ();
        credentials.UserName = "alessandro";
        credentials.Password = "ireland";
        bool ok = false;
        try
        {
            _notification.Visible = true;
            _notification.Running = true;

            FlagFtp.FtpClient ftpClient = new FtpClient (credentials);
            string uri = "ftp://192.168.0.102/GECOl.sqlite";
            FtpFileInfo ftpFileInfo = ftpClient.GetFileInfo (new Uri (uri));
            FtpStream ftpstream = ftpClient.OpenRead (ftpFileInfo);
            byte[] buffer = new byte[ftpFileInfo.Length];
            ftpstream.Read (buffer, 0,(int) ftpFileInfo.Length);
            DependencyService.Get<IFiles> ().SaveBytes (filename, buffer);
            ok = true;
        }
        catch(Exception ex) {
            error = ex.Message;
        }
        finally {
            _notification.Visible = false;
            _notification.Running = false;
        }

        return ok;
    }

    public class Notification : INotifyPropertyChanged
    {
        private bool _visible = false ;
        public bool Visible {
            get { return _visible; }
            set { 
                if (value.Equals (_visible))
                    return;
                _visible = value;
                OnPropertyChanged ();
            }
        }

        private bool _running = false;
        public bool Running  {
            get { return _running; }
            set { 
                if (value.Equals (_running))
                    return;
                _running = value;
                OnPropertyChanged ();
            }

        }

        public event PropertyChangedEventHandler PropertyChanged;

        void OnPropertyChanged([CallerMemberName]String propertyName=null)
        {
            var handler=PropertyChanged;
            if(handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

}

Posts

  • adamkempadamkemp USInsider, Developer Group Leader mod

    It doesn't do any good to update those properties if you're not doing anything async. You're not giving the UI thread time to update the UI. You have to avoid blocking the UI thread.

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    so, the problem is that I don't use async in the ftp?

  • adamkempadamkemp USInsider, Developer Group Leader mod

    I'm not necessarily saying you have to use the async keyword, but you have to do something asynchronously. You have to let the UI thread do stuff while you're doing the transfer.

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Adam, I know that this is not the right place, but you can kindly suggest me how to implement the ftp asynchronous in the xamarin.forms.page? or report me a link that describes how to do it?

  • adamkempadamkemp USInsider, Developer Group Leader mod

    This page tells you how to use await with IAsyncResult:
    http://www.justjuzzy.com/2012/10/turn-iasyncresult-code-into-await-keyword/

    And there are many pages explaining how async/await work so you should just google that.

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Hi. I've used ReadAsyncCallback for ftpstream.beginRead. and it works well.
    I've inserted binding for Button

            buttonRetry.SetBinding (Button.TextProperty, "OkFtp");
            buttonRetry.SetBinding (Button.IsEnabledProperty, "IsButtonEnable");
    

    and these also work well.

    Only activity indicator does not appear...
    Now I think it's something else. In some example I've seen that activityIndicator is in a Grid, not in a stackLayout... could this be the reason?

  • adamkempadamkemp USInsider, Developer Group Leader mod

    Try making the activity indicator always visible and always running. If you still can't see it then it's a layout issue. Otherwise you're probably still not doing the async stuff right.

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Ok Adam, Thanks for you patience and suggestions. I'll do some tests and I'll write in this thread what I found

Sign In or Register to comment.