SelectedItem in TabbedPage.xaml does not work Xamarin.Form - xamarin

Hey everyone Good Day I have tabbed created in xaml, I prefer xaml because I have login in xaml code. My Code
Tab.xaml
<TabbedPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:FormsSample.Views;assembly=FormsSample"
x:Class="FormsSample.Views.LoginPage"
x:Name="TbPage">
<TabbedPage.Children>
<ContentPage x:Name="TbLog" Title="Login">
</ContentPage>
<ContentPage x:Name="TbSch" Title="Schedule">
</ContentPage>
<ContentPage x:Name="TbLis" Title="Customers">
</ContentPage>
</TabbedPage.Children>
</TabbedPage>
Tab.xaml.cs
namespace FormsSample.Views
{
public partial class LoginPage : TabbedPage
{
private readonly TabbedPage _tbPage;
private readonly ContentPage _tbList;
private readonly ContentPage _tbLogn;
public LoginPage()
{
InitializeComponent ();
_tbPage = this.FindByName<TabbedPage>("TbPage");
_tbList = this.FindByName<ContentPage>("TbLis");
_tbLogn = this.FindByName<ContentPage>("TbLog");
RunTime();
}
private void RunTime()
{
_tbPage.CurrentPage = _tbLogn;
if (_tbPage.SelectedItem == _tbPage.Children[2])
{
DisplayAlert("Tab", "Hello World", "OK");
}
}
}
}
changing to
_tbPage.SelectedItem == _tbList
Its similar nothing happen, How to solve this? thanks a lot.

This may not be fancy but it works for me :D
this.CurrentPageChanged += (o, e) =>
{
var i = this.Children.indexOf(this.CurrentPage);
if(i == 1 && UsrType == 2)
{
DisplayAlert("Admin", "Administrator Privilege required!", "OK");
this.CurrentPage = _tbLog;
}
};

I set SelectedItem to null first, before setting it to the page I wanted to show.

Related

Xamarin Forms Binding not populated until reload

I have a Xamarin Forms app that shows a picture that is bound to a class (RandomChallenge). The class is generated in the view model and assigned. The class has a Uri property which we want to bind to an image in the view.
When the app loads it doesn't show any picture, even though RandomChallenge is not null. If I make a change to the UI code whilst debugging and save it, when the debugger reloads the image is visible. Its as if the RandomChallenge class gets populated after the page renders? If I was to put a break point on the line RandomChallenge = await ChallengeDataStore.GetRandomChallenge(); RandomChallenge is populated.
ViewModel
public class MainMenuViewModel : BaseViewModel
{
public ICommand OpenWebCommand { get; }
public IdentificationChallenge RandomChallenge { get; set; }
public Command LoadChallengeCommand { get; set; }
public MainMenuViewModel()
{
Title = "Main Menu";
LoadChallengeCommand = new Command(async () => await ExecuteLoadChallengeCommand());
this.LoadChallengeCommand.Execute(null);
}
async Task ExecuteLoadChallengeCommand()
{
if (IsBusy)
return;
try
{
RandomChallenge = await ChallengeDataStore.GetRandomChallenge();
Debug.WriteLine("TEst");
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
IsBusy = false;
}
}
}
UI
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:microcharts="clr-namespace:Microcharts.Forms;assembly=Microcharts.Forms"
mc:Ignorable="d"
x:Class="HOG.MobileApp.Views.MainMenuPage"
xmlns:vm="clr-namespace:HOG.MobileApp.ViewModels"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
Title="{Binding Title}">
<ContentPage.Resources>
<ResourceDictionary>
<Color x:Key="Primary">#72a230</Color>
<Color x:Key="Accent">#72a230</Color>
<Color x:Key="LightTextColor">#72a230</Color>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.ToolbarItems>
<ToolbarItem Text="Help" />
</ContentPage.ToolbarItems>
<ContentPage.Content>
<Image Source="{ Binding RandomChallenge.Picture }" HeightRequest="450" WidthRequest="450" />
</ContentPage.Content>
So the answer was to call OnPropertyChanged when RandomChallenge is assigned. The ViewModel did implement INotifyPropertyChanged on its parent class.
async Task ExecuteLoadChallengeCommand()
{
if (IsBusy)
return;
try
{
RandomChallenge = await ChallengeDataStore.GetRandomChallenge();
OnPropertyChanged("RandomChallenge");
Debug.WriteLine("TEst");
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
IsBusy = false;
}
}

How to create a Xamarin Tooltip in code-behind

I am testing using the following example. https://github.com/CrossGeeks/TooltipSample
The sample works fine, it even works with Labels (sample uses buttons, images and boxviews). The issue is in my main App I need to create the tooltips in code behind.
To test how to do it, in the very same solution (from that above example) I created a TestPage and made it my MainPage in App.xaml.cs. The XAML looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ToolTipSample.TestPage">
<ContentPage.Content>
<StackLayout
x:Name="mainLayout"
BackgroundColor="Yellow">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="Handle_Tapped"/>
</StackLayout.GestureRecognizers>
</StackLayout>
</ContentPage.Content>
The code-behind looks like this:
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using ToolTipSample.Effects;
namespace ToolTipSample
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TestPage : ContentPage
{
public TestPage()
{
InitializeComponent();
var actionLabel = new Label
{
Text = "Show Tooltip",
WidthRequest = 150,
VerticalOptions = LayoutOptions.StartAndExpand,
HorizontalOptions = LayoutOptions.Center,
BackgroundColor = Color.Wheat
};
// Add tooltip to action label
TooltipEffect.SetPosition(actionLabel, TooltipPosition.Bottom);
TooltipEffect.SetBackgroundColor(actionLabel, Color.Silver);
TooltipEffect.SetTextColor(actionLabel, Color.Teal);
TooltipEffect.SetText(actionLabel, "This is the tooltip");
TooltipEffect.SetHasTooltip(actionLabel, true);
actionLabel.Effects.Add(Effect.Resolve($"CrossGeeks.{nameof(TooltipEffect)}"));
mainLayout.Children.Add(actionLabel);
}
void Handle_Tapped(object sender, System.EventArgs e)
{
foreach (var c in mainLayout.Children)
{
if (TooltipEffect.GetHasTooltip(c))
{
TooltipEffect.SetHasTooltip(c, false);
TooltipEffect.SetHasTooltip(c, true);
}
}
}
}
}
All other code unchanged.
When I tap the label, the tooltip appears as expected. But when I tap the background it does not disappear (like those created in XAML in the sample).
One other thing. If I tap twice it disappears.
Can anyone see what I am missing?
Thanks.
According to your description and code, you can delete the following line code to achieve your requirement.
actionLabel.Effects.Add(Effect.Resolve($"CrossGeeks.{nameof(TooltipEffect)}"));
You don't need to add effect for control when page load, because this effect will be added when you click this control by these code:
static void OnHasTooltipChanged(BindableObject bindable, object oldValue, object newValue)
{
var view = bindable as View;
if (view == null)
{
return;
}
bool hasTooltip = (bool)newValue;
if (hasTooltip)
{
view.Effects.Add(new ControlTooltipEffect());
}
else
{
var toRemove = view.Effects.FirstOrDefault(e => e is ControlTooltipEffect);
if (toRemove != null)
{
view.Effects.Remove(toRemove);
}
}
}

Xamarin Forms - Hide navigation bar in MasterDetailPage

I need hide navigation bar in xamarin forms 3.0.
I try this, but dont work:
Hide Navigation Bar on MasterDetailPage
I want hide navigation bar for create a custom bar, also I need a way to open menu.
Thanks.
App.xaml.cs
public partial class App : Application
{
public App ()
{
InitializeComponent();
MainPage = new MainPage();
}
...
MainPage.xaml.cs
public partial class MainPage : MasterDetailPage
{
public List<MasterPageItem> menuList { get; set; }
public MainPage()
{
InitializeComponent();
menuList = new List<MasterPageItem>();
menuList.Add(new MasterPageItem() { Title = "Home", Icon = "home.png", TargetType = typeof(HomePage) });
menuList.Add(new MasterPageItem() { Title = "Settings", Icon = "setting.png", TargetType = typeof(SettingsPage) });
menuList.Add(new MasterPageItem() { Title = "Help", Icon = "help.png", TargetType = typeof(HelpPage) });
navigationDrawerList.ItemsSource = menuList;
var navPage = new NavigationPage((Page)Activator.CreateInstance(typeof(HomePage)));
//I try this:
NavigationPage.SetHasNavigationBar(navPage, false);
NavigationPage.SetHasBackButton(navPage, false);
Detail = navPage;
}
...
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App3"
x:Class="App3.MainPage">
<MasterDetailPage.Master>
<ContentPage Title="Menu">
<Grid BackgroundColor="Transparent">
<StackLayout Grid.Row="1" Spacing="15">
...
</StackLayout>
</Grid>
</ContentPage>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage>
</NavigationPage>
</MasterDetailPage.Detail>
</MasterDetailPage>
Source repo:
https://github.com/uiahhh/stackoverflow/tree/master/HideNavBar
I want remove this navbar in red circle:
On the detail page you have to remove the navigation bar with NavigationPage.SetHasNavigationBar(this, false); in the constructor right after InitializeComponent()
public partial class MyPage : NavigationPage
{
public MyPage()
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
}
}
In addition to Pedro's answer, you can also hide the navigation bar in your .xaml file. For example:
<ContentPage NavigationPage.HasNavigationBar="False">
...
</ContentPage>
Note: This works in Xamarin 4.0 but I haven't tested it in 3.0.

Xamarin Forms ListView text not displayed

I'm new to Xamarin Forms, I'm following the official tutorial for learning Xamarin forms. While learning about navigation using Phoneword project of the following link
https://developer.xamarin.com/guides/xamarin-forms/getting-started/hello-xamarin-forms-multiscreen/quickstart/
The listview text is not appearing. Please help me!
CallHistoryPage.xaml: Here the listview is there.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App1;assembly=App1"
x:Class="App1.CallHistoryPage"
Title="Call History">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="20, 40, 20, 20"/>
<On Platform="Android" Value="20"/>
</OnPlatform>
</ContentPage.Padding>
<StackLayout>
<ListView ItemsSource="{x:Static local:App.PhoneNumbers}" />
</StackLayout>
</ContentPage>
MainPage.xaml.cs: SourceItem values are updated in this class.
namespace App1
{
public partial class MainPage : ContentPage
{
string translatedNumber;
public MainPage()
{
InitializeComponent();
}
void OnTranslate(object sender, EventArgs e)
{
translatedNumber = PhonewordTranslator.ToNumber(phoneNumberText.Text);
if (!string.IsNullOrWhiteSpace(translatedNumber))
{
callButton.IsEnabled = true;
callButton.Text = "Call " + translatedNumber;
}
else
{
callButton.IsEnabled = false;
callButton.Text = "Call";
}
}
async void OnCall(object sender, EventArgs e)
{
if (await this.DisplayAlert(
"Dial a Number",
"Would you like to call " + translatedNumber + "?",
"Yes",
"No"))
{
var dialer = DependencyService.Get<IDialer>();
if (dialer != null)
{
App.PhoneNumbers.Add(translatedNumber);
callHistoryButton.IsEnabled = true;
dialer.Dial(translatedNumber);
}
}
}
async void OnCallHistory(object sender, EventArgs e)
{
await Navigation.PushAsync(new CallHistoryPage());
}
}
}
App.xaml.cs: Sourceitem for listview is in this class
namespace App1
{
public partial class App : Application
{
public static IList<string> PhoneNumbers { get; set; }
public App()
{
InitializeComponent();
PhoneNumbers = new List<string>();
MainPage = new NavigationPage(new MainPage());
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
}
For more details please follow the link added above. Same tutorial is followed.
You forgot to 'tell' ListView what to display.
<ListView ItemsSource="{x:Static local:App.PhoneNumbers}" />
creates a ListView with empty cells, hence they are not displaying anything. You'll have to set the ListView.ItemTemplate in order to display anything
<ListView ItemsSource="{x:Static local:App.PhoneNumbers}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding .}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The BindingContext within the DataTemplate will be the respective item from App.PhoneNumbers. Since the items are bare strings we bind to ., which refers to the bound element itself.
See here for ListViews in Xamarin.Forms.
You have not added any numbers in PhoneNumbers list. Add number first in PhoneNumbers list and then check.
public App()
{
InitializeComponent();
PhoneNumbers = new List<string>();
PhoneNumbers.Add("123456789");
PhoneNumbers.Add("178967897");
PhoneNumbers.Add("178945678");
MainPage = new NavigationPage(new MainPage());
}
I think you have forget to take input from user.So add this line in OnCall method
translatedNumber = PhonewordTranslator.ToNumber(phoneNumberText.Text);
Try this,
async void OnCall(object sender, EventArgs e)
{
translatedNumber = PhonewordTranslator.ToNumber(phoneNumberText.Text);
if (await this.DisplayAlert(
"Dial a Number",
"Would you like to call " + translatedNumber + "?",
"Yes",
"No"))
{
var dialer = DependencyService.Get<IDialer>();
if (dialer != null)
{
App.PhoneNumbers.Add(translatedNumber);
callHistoryButton.IsEnabled = true;
dialer.Dial(translatedNumber);
}
}
}

System.NullReferenceException Xamarin Maps

I'm getting a NullException when will display the map, but can not detect;
I tried to change the name of the maps, locazation, etc., but without success.
You may be able to identify where is my mistake, please help me!
public partial class LocationPage : ContentPage
{
public Clinica _clinica;
public LocationPage(Clinica clinica)
{
InitializeComponent();
Clinica = clinica;
SetupMap();
}
public Clinica Clinica
{
get
{
return _clinica;
}
set
{
_clinica = value;
}
}
protected override void OnAppearing()
{
base.OnAppearing();
// Typically, is preferable to call into the viewmodel for OnAppearing() logic to be performed,
// but we're not doing that in this case because we need to interact with the Xamarin.Forms.Map property on this Page.
// In the future, the Map type and it's properties may get more binding support, so that the map setup can be omitted from code-behind.
SetupMap();
}
void SetupMap()
{
if (Device.OS != TargetPlatform.WinPhone && Device.OS != TargetPlatform.Windows)
{
var pin = new Pin()
{
Type = PinType.Place,
Position = new Position(Clinica.Latitude, Clinica.Longitude),
Label = Clinica.Nome
};
clinicaMap.Pins.Clear();
clinicaMap.Pins.Add(pin);
clinicaMap.MoveToRegion(MapSpan.FromCenterAndRadius(pin.Position, Distance.FromMiles(10)));
}
}
}
}
LocationPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps"
x:Class="CartaoDeTodos.View.LocationPage">
<StackLayout>
<maps:Map x:Name="clinicaMap"
VerticalOptions="FillAndExpand"/>
</StackLayout>
</ContentPage>

Resources