I Want to Run a Method Every Minute That'S Started from My Onappearing(). Do I Need to Run This as a Task

I want to run a method every minute that's started from my OnAppearing(). Do I need to run this as a task?

You can do this simpler by returning the correct value from Device.StartTimer, to repeat true, to not repeat false and not use a StopWatch. (source states that While the callback returns true, the timer will keep recurring. And as you see from the source, the method doesn't need a Func<Task<bool>> it only needs a Func<bool> callback so there is no need to use a Task.)

in the class

volatile bool run;

in OnAppearing

run = true;
Device.StartTimer(new TimeSpan(0, 1, 0), () => {
if (run) { /*do what you want;*/ return true; }
else { return false; }
});

in OnDisappearing

run = false;


EDIT - as requested by OP

Here is the code. I am leaving my original answer to help anyone else who needs this.

volatile bool run;

protected async override void OnAppearing()
{
base.OnAppearing();
BindingContext = vm;
cts = new CancellationTokenSource();
if (Settings.mode == MO.Practice)
{
run = true;
Device.StartTimer(new TimeSpan(0, 1, 0), () =>
{
if (run)
{
if (App.DB.ReducePoints() == true)
Device.BeginInvokeOnMainThread(() =>
{
vm.PifInfo = GetPifInfo();
});
return true;
}
else { return false; }
});
await GetCards(cts.Token);
}
}

protected override void OnDisappearing()
{
run = false;
Unsubscribe();
cts.Cancel();
base.OnDisappearing();
}

With code that opens a new page in an async method, do I need to run that on the main thread and if so how can I do this?

To run code on the UI thread (or the mainthread) you should use the code below which forces the code to run on the MainThread.

Be aware that any async method 'could' have code running in any other thread as Xamarin sees fit.

There are some smart ways for the program to know if your code should run on the MainThread whe using async methods.

If you want to know the full ins and outs please check this article that my manager sent me:
https://devblogs.microsoft.com/dotnet/configureawait-faq/

Xamarin.Forms.Device.BeginInvokeOnMainThread(() =>
{
App.NavigationService.SetAsRoot(nameof(Views.StartPage));
});

For calling async await methods:

 Xamarin.Forms.Device.BeginInvokeOnMainThread(async() =>
{
await App.NavigationService.NavigateTo(nameof(Views.StartPage));
});

how to call async method in MainPage

If you don't want to call this in the OnAppearing() method and specifically in the contructor, you can do this (watch out for possible thread blocking though):

public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();

// watch out for possible thread blocking!
Task.Run(async() =>
{
await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
});
}
}

OnApearing() method is not firing second time in Mater details page of xamarin forms

I used IsPresentedChanged property. Please check the below code.

public MainMasterDetailPage()
{
InitializeComponent();

NavigationPage.SetHasBackButton(this, false);
NavigationPage.SetHasNavigationBar(this, false);
ListOfSettings.IsVisible = false;
this.IsPresented = false;
Detail = new NavigationPage(new DashboardTabbedPage());

this.IsPresentedChanged += hideSettingMenu;

}
public void hideSettingMenu(object sender, EventArgs args)
{
ListOfSettings.IsVisible = false;
}

Getting initial data pattern in Xamarin Forms

create an Init method on your VM

public class DataFeedViewModel : BaseViewModel
{
public DateFeedViewModel()
{
Title = "My Feed";
}

public List<FeedItem> Feed { get; set; }

public async void Init()
{
Feed = await _myApiService.GetFeed();
}
}

and then have your page call it

private DataFeedViewModel VM { get; set; }

public MainPage()
{
InitializeComponent();
this.BindingContext = VM = new DataFeedViewModel();
}

protected override async void OnAppearing()
{
base.OnAppearing();

await VM.Init();
}

How can I detect focus on child view inside a Tabbed Page in Xamarin.Forms?

Just like
ToolmakerSteve sayed, the tabbedpage has the CurrentPageChanged event, so you can override the OnCurrentPageChanged() method of the TabbedPage. Such as:

public partial class TabbedPage1 : TabbedPage
{
public TabbedPage1()
{
InitializeComponent();

}

protected override void OnCurrentPageChanged()
{

if(CurrentPage == Children[0])//Children[0] is the page A
{
....
}else if(CurrentPage == Children[1])//Children[1] is the page B
{
.....
}
else
{
......
}


base.OnCurrentPageChanged();
}
}

OnAppearing() method is performing before calling the OnCurrentPageChanged() method

In Android, onAppearing is called before OnCurrentPageChanged while in iOS OnCurrentPageChanged is called before onAppearing.

1.As jgoldberger suggested, you can call method in each Page after CurrentPageChanged:

    override protected void OnCurrentPageChanged()
{
if (this.CurrentPage.Title == "Week")
{
Xamarin.Forms.Application.Current.Properties["weekOnAppear"] = true;

NavigationPage naviPage = this.Children[0] as NavigationPage;
WeekPage page = naviPage.RootPage as WeekPage;
page.test();

}else if (this.CurrentPage.Title == "Month")
{
Xamarin.Forms.Application.Current.Properties["monthOnAppear"] = true;

NavigationPage naviPage = this.Children[1] as NavigationPage;
MonthPage page = naviPage.RootPage as MonthPage;
page.test();
}
else
{
Xamarin.Forms.Application.Current.Properties["dayOnAppear"] = true;

NavigationPage naviPage = this.Children[2] as NavigationPage;
DayPage page = naviPage.RootPage as DayPage;
page.test();
}

base.OnCurrentPageChanged();
}
}

2.You can use messaging-center to notify specific page to perform some actions after CurrentPageChanged:

    override protected void OnCurrentPageChanged()
{
string testStr;

if (this.CurrentPage.Title == "Week")
{
testStr = "Week";
}else if (this.CurrentPage.Title == "Month")
{
testStr = "Month";
}
else
{
testStr = "Day";
}

MessagingCenter.Send<object, string>(new object(), "CurrentPageChanged", testStr);

base.OnCurrentPageChanged();
}

And in each page:

public partial class MonthPage : ContentPage
{
public MonthPage()
{
InitializeComponent();

MessagingCenter.Subscribe<object, string>(new object(), "CurrentPageChanged", async (sender, arg) =>
{
if (arg == "Month")
{
Console.WriteLine(arg);
//do something
}
});
}

public void test() {

Console.WriteLine("test");
//do something
}
}

BTW, you should use if...else if...else instead of if...if...else in your control statement.



Related Topics



Leave a reply



Submit