Tell ActivityIndicator to show yourself and then navigate to another page - c#

On Xamarin.Forms Project, I am trying to tellActivityIndicator to show yourself and then navigate to another page
activityIndicatorObject = new ActivityIndicator()
{
HorizontalOptions = LayoutOptions.CenterAndExpand,
Color = Color.Red,
IsVisible = false,
IsRunning = false,
IsEnabled = false,
BindingContext = this,
};
ViewBookButton = new Button{ Text = "view book" };
ViewBookButton.Clicked += ViewBook;
protected void ViewBook(Object sender,EventArgs e)
{
//Go To View Book Page
activityIndicatorObject .IsVisible = true;
activityIndicatorObject .IsRunning = true;
activityIndicatorObject .IsEnabled = true;
activityIndicatorObject .SetBinding(ActivityIndicator.IsVisibleProperty, "IsBusy");
this.IsBusy = true;
Navigation.PushAsync(new BookPage());
this.IsBusy = false;
}
ActivityIndicator doesn't showing? How I can make it showing?

As I understand you tell ActivityIndicator show yourself and then navigate to another page. And new page hasn't own ActivityIndicator. I would like to suggest you make your hard operations in OnAppearing method of BookPage.
protected override void OnAppearing()
{
base.OnAppearing();
activityIndicator.IsVisible = true;
// Some hard operations
activityIndicator.IsVisible = false;
}
Or use binding instead of activityIndicator.IsVisible = true;

Related

Set Back Button Title on Xamarin Forms C#

im quite new to c# and Xamarin and I've just encountered a problem. I can't seem to be able to set the back button title on a navigation page. Ive tried using the static SetBackButtonTitle method but it does not seem to set the back button to the title I want which is
'Test' but instead its giving me the 'default' title which is "Back".
// The root page of your application
var content = new ContentPage();
var CompanyName = new Label();
CompanyName.HorizontalTextAlignment = TextAlignment.Center;
CompanyName.Text = "Test";
var NextPage = new Button();
NextPage.Text = "Next Page";
NextPage.Font = Font.SystemFontOfSize(NamedSize.Large);
NextPage.BorderWidth = 1;
NextPage.HorizontalOptions = LayoutOptions.Center;
NextPage.VerticalOptions = LayoutOptions.CenterAndExpand;
var layout = new StackLayout();
layout.VerticalOptions = LayoutOptions.CenterAndExpand;
layout.Children.Add(CompanyName);
layout.Children.Add(NextPage);
content.Content = layout;
var content2 = new ContentPage();
var navigation = new NavigationPage(content);
NavigationPage.SetHasBackButton(navigation,true);
NavigationPage.SetBackButtonTitle(navigation,"Test");
NextPage.Clicked += NextPageClicked;
async void NextPageClicked(object sender, EventArgs e)
{
await navigation.PushAsync(content2);
}
MainPage = navigation;
}
If you want to change the back button's title(at the left in the navigation bar) in the second page, you should call the method SetBackButtonTitle with first page as parameter. So please modify NavigationPage.SetBackButtonTitle(navigation,"Test"); to NavigationPage.SetBackButtonTitle(content,"Test");
For those who use Xamarin.Forms WPF if you want to change back button title you can do this:
protected override void OnDisappearing()
{
base.OnDisappearing();
Title = "";
}
protected override void OnAppearing()
{
base.OnAppearing();
Title = "MyTitle";
}

Set UI element visible in Xamarin C# and then call asynchronous function

Can anybody help me with this code in my Xamarin project. I am trying to set a loading wheel (to signify that an action is happening and to let the user know to wait) when the "Login" button is clicked. For some reason since the function is asynchronous the loading wheel is never set to visible when the API code is run. It just fails to show up when I click login, however, it still does the login function.
// Defined up above in the file
var loginButton = new Button
{
Text = "Login",
};
loginButton.BackgroundColor = Color.Navy;
loginButton.TextColor = Color.White;
loginButton.Clicked += OnLoginButtonClicked;
async void OnLoginButtonClicked(object sender, EventArgs e)
{
loadingWheel.IsVisible = true;
try
{
var restUrl = "*******";
var content = string.Empty;
using (var client = new HttpClient())
{
string body = "{\"UserName\":\"" + usernameEntry.Text + "\", \"Password\":\"" + passwordEntry.Text + "\"}";
var contentType = new StringContent(body, Encoding.UTF8, "application/json");
var result = client.PostAsync(restUrl, contentType).Result;
content = await result.Content.ReadAsStringAsync();
}
if (content.ToLower() != "false")
{
var menuPage = new MenuPage();
NavigationPage = new NavigationPage(new HomePage());
RootPage = new Views.MainPage();
RootPage.Master = menuPage;
RootPage.Detail = NavigationPage;
MainPage = RootPage;
}
else
{
messageLabel.Text = "Username or password incorrect. Please try again.";
passwordEntry.Text = string.Empty;
}
}
catch (Exception ex)
{
messageLabel.Text = "Please check the internet connection for the connectivity.";
}
}
If I comment out the entire try block then the loading wheel does show up. It just does not work with the code in there.
Can anybody help me solve this problem? Thanks.
I think you can try with BeginInvokeOnMainThread
Device.BeginInvokeOnMainThread (() => {
loadingWheel.IsVisible = true;
});
UPDATE
I have also create this REPO... it works without BeginInvodeOnMainThread
public class MyPage6 : ContentPage
{
ActivityIndicator _ac = new ActivityIndicator { IsVisible = false, IsRunning = false };
public MyPage6()
{
Button b = new Button {Text = "Press for ActivityIndicator" };
b.Clicked += B_Clicked;
Content = new StackLayout
{
Children = {
_ac,
b,
new Label { Text = "Hello ContentPage" }
}
};
}
async void B_Clicked(object sender, EventArgs e)
{
_ac.IsRunning = true;
_ac.IsVisible = true;
await Task.Delay(2000);
_ac.IsRunning = false;
_ac.IsVisible = false;
}
}

ZXing.Net Back Navigation C#

I am using ZXing.Net camera barcode scanner, xamarin forms, and C# and it appears to be working good. But I have an issue where if I go the the next page via Navigation.PushAsync(), then click the Back Navigation Button, the ZXingScannerPage camera will not reload...(it will only be a still image of the last pic taken)...how do I reload the ZXingScannerPage so that the camera is actively upon pressing the Back Navigation? Is the anyway to refresh the camera view attached to the page?
Use the following code. Stop the scanning as soon as scanning is done. Don't do a manual manuver.
Entry objScanner= new Entry();
objScanner.Placeholder = "Barcode";
objScanner.Keyboard = Keyboard.Numeric;
objScanner.HorizontalOptions = LayoutOptions.StartAndExpand;
objScanner.WidthRequest = Application.Current.MainPage.Width - 40;
objScanner.SetBinding(Entry.TextProperty, "ElementValue", BindingMode.TwoWay);
objScanner.BindingContext = control;
layout.Children.Add(objScanner);
objScanner.Focused += async (s, e) =>
{
var scanPage = new ZXingScannerPage();
await Navigation.PushAsync(scanPage);
scanPage.OnScanResult += (result) =>
{
// Stop scanning
scanPage.IsScanning = false;
// Pop the page and show the result
Device.BeginInvokeOnMainThread(async () =>
{
await Navigation.PopAsync();
objScanner.Text = result.Text;
// await DisplayAlert("Scanned Barcode", result.Text, "OK");
});
};
};
The solution that I found that works for me to allow back navigation using ZXing Scanner page is to remove all instances of ZXing Scanner page before push a new instance of the page to the navigation stack. In your navigation.cs, when you get ready to push the page, use this:
foreach(var x in _navigation.Navigation.NavigationStack.ToList())
{
if((x.GetType() == typeof(/* name of your scanner page */)))
{
_navigation.Navigation.RemovePage(x);
}
}
var page = new /* your scanner page */();
_navigation.PushAsync( /* your scanner page */);
I have found a workaround which may be useful.
On content page, create a local content variable.
If I instantiate the scanner and add it to Content in OnAppearing method, then set Content = null OnDisappearing method. Nulling the Content seems to trigger the necessary cleanups up the stack.
Here's my code:
public class QrCodeScanPage : ZXingScannerPage
{
View _content;
public QrCodeScanPage()
{
InitScanner();
}
void InitScanner()
{
IsAnalyzing = true;
IsScanning = true;
DefaultOverlayTopText = "Align the barcode within the frame";
DefaultOverlayBottomText = string.Empty;
OnScanResult += ScanPage_OnScanResult;
Title = "Scan Code";
var item = new ToolbarItem
{
Text = "Cancel",
Command = new Command(async () =>
{
IsScanning = false;
await Navigation.PopAsync();
})
};
if (Device.RuntimePlatform != Device.iOS)
item.IconImageSource = "toolbar_close.png";
ToolbarItems.Add(item);
}
void ScanPage_OnScanResult(ZXing.Result result)
{
Device.BeginInvokeOnMainThread(async () =>
{
IsScanning = false;
IsAnalyzing = false;
await Navigation.PushAsync(new QrCodeScanResultPage());
});
}
protected override void OnAppearing()
{
IsScanning = true;
IsAnalyzing = true;
base.OnAppearing();
if (Content != null)
{
_content = Content;
}
if (Content == null)
{
Content = _content;
}
}
protected override void OnDisappearing()
{
base.OnDisappearing();
Content = null;
}
}

SystemTray for Pivot Item content

I have a Pivot Control in MainPage.xaml page. I add in the PageOne.xaml.cs as pivot item using
private void OnLoadingPivotItem(object sender, PivotItemEventArgs e)
{
if (e.Item.Content != null)
{
// Content loaded already
return;
}
Pivot pivot = (Pivot)sender;
if (e.Item == pivot.Items[0])
{
e.Item.Content = new PageOne();
}
}
Thing is not working so fine, but I have tried to fix them, for example,
// NavigationService.Navigation(new Uri());
// need to change to
(App.Current as App).RootFrame.Navigate( new Uri());
// ApplicationBar for PivotItem
appBar = ((PhoneApplicationPage)((PhoneApplicationFrame)Application.Current.RootVisual).Content).ApplicationBar;
Now, I need to show ProgressIndicator on my PivotControl MainPage.xaml from my PageOne.xaml.cs code.
_progressIndicator = new ProgressIndicator
{
IsIndeterminate = true,
IsVisible = false,
};
SystemTray.SetProgressIndicator(this, _progressIndicator);
But progressIndicator doesn't show, what should I do? My guess is to call the SystemTray of RootFrame but I am not sure how to.
Try change the property IsVisible to true.
Wish this can help you.
I need to pass MainPage as reference to PageOne, and put it as parameter when using SystemTray.SetProgressIndicator.
In MainPage.xaml.cs
e.Item.Content = new PageOne(this);
Here is the constructor code from PageOne.xaml.cs
public PageOne(MainPage page) {
_progressIndicator = new ProgressIndicator
{
IsIndeterminate = true,
IsVisible = false,
};
SystemTray.SetProgressIndicator(page, _progressIndicator);
}

Slow app changing page in WP8

I have an app with a ListBox; when the user taps an item i launch a new page that invoke a MVVM method and the fills its ListBox. When the user taps the first ListBox it does not change page immediately, waits 2-3 seconds and then shows the new page and it is not responsive. How can i activate the new page, showing the ProgressIndicator and fill the new list?
Here is the code for the second list:
protected override async void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
int id;
if (NavigationContext.QueryString.ContainsKey("id"))
{
id = Convert.ToInt16(NavigationContext.QueryString["id"]);
SystemTray.SetIsVisible(this, true);
SystemTray.SetOpacity(this, 0.5);
progressIndicator = new ProgressIndicator();
progressIndicator.IsVisible = true;
progressIndicator.IsIndeterminate = true;
SystemTray.SetProgressIndicator(this, progressIndicator);
var x=await App.viewModel.MyDBMethod(id);
this.DataContext = App.viewModel;
this.mPivot.SelectedIndex = 0;
progressIndicator.IsVisible = false;
progressIndicator.IsIndeterminate = false;
}
}
}

Categories