Make icon invisible in shell - xaml

I am trying to disable the hamburger icon is there a way to do that using shell I tried setting the following but it still appears in the simulator.
I want the flyout effect to still happen but I don't want the Hambugger icon their.
<Shell.Resources>
<ResourceDictionary>
<Color x:Key="NavigationPrimary">#2196F3</Color>
<Style x:Key="BaseStyle" TargetType="Element">
<Setter Property="Shell.BackgroundColor" Value="{StaticResource NavigationPrimary}" />
<Setter Property="Shell.ForegroundColor" Value="White" />
<Setter Property="Shell.TitleColor" Value="White" />
<Setter Property="Shell.DisabledColor" Value="#B4FFFFFF" />
<Setter Property="Shell.UnselectedColor" Value="#95FFFFFF" />
<Setter Property="Shell.TabBarBackgroundColor" Value="{StaticResource NavigationPrimary}" />
<Setter Property="Shell.TabBarForegroundColor" Value="White"/>
<Setter Property="Shell.TabBarUnselectedColor" Value="#95FFFFFF"/>
<Setter Property="Shell.TabBarTitleColor" Value="White"/>
</Style>
<Style TargetType="TabBar" BasedOn="{StaticResource BaseStyle}" />
</ResourceDictionary>
</Shell.Resources>
<Shell.FlyoutHeader>
<Grid BackgroundColor="Black">
<Label Text="Test"
TextColor="White"
FontAttributes="Bold"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center" />
</Grid>
</Shell.FlyoutHeader>
<FlyoutItem Title="Collect Data" >
<Tab>
<ShellContent Title="Configuration"
ContentTemplate="{DataTemplate local:AboutPage}" />
<ShellContent Title="Collect Data"
ContentTemplate="{DataTemplate local:ItemsPage}" />
</Tab>
</FlyoutItem>
<FlyoutItem Title="About">
<ShellContent ContentTemplate="{DataTemplate local:AboutPage}" />
</FlyoutItem>

Try to set the BackgroundColor of shell to White, it would hide the hamburger icon.
<Shell
....
BackgroundColor="White"
....>
Or you could use the custom renderer to reset the toolbar background color to white. It would hide the icon as well.
[assembly: ExportRenderer(typeof(AppShell), typeof(MyShellRenderer))]
namespace ShellDemo2.Droid
{
public class MyShellRenderer : ShellRenderer
{
public MyShellRenderer(Context context) : base(context)
{
}
protected override IShellToolbarAppearanceTracker CreateToolbarAppearanceTracker()
{
return new MyToolbarAppearanceTracker(this);
}
protected override IShellTabLayoutAppearanceTracker CreateTabLayoutAppearanceTracker(ShellSection shellSection)
{
return new MyTabLayoutAppearanceTracker(this);
}
}
public class MyToolbarAppearanceTracker : IShellToolbarAppearanceTracker
{
private MyShellRenderer myShellRenderer;
public MyToolbarAppearanceTracker(MyShellRenderer myShellRenderer)
{
this.myShellRenderer = myShellRenderer;
}
public void Dispose()
{
}
public void ResetAppearance(Android.Support.V7.Widget.Toolbar toolbar, IShellToolbarTracker toolbarTracker)
{
toolbar.SetBackgroundColor(Android.Graphics.Color.White);
}
public void SetAppearance(Android.Support.V7.Widget.Toolbar toolbar, IShellToolbarTracker toolbarTracker, ShellAppearance appearance)
{
}
}
}

Related

How to build string for IconCode in Xamarin

How can I dynamically connect Material icon code with prefix \u in Xamarin?
This not work:
string iconCode = "e87e";
Label label = new Label
{FontFamily = "IconMaterial", Text = $"\u{iconCode}"}
And How can I do the same thing in XAML code?
Thank you!
If you want to use the Material icon, you need to set the FontFamily first.
<ContentPage.Resources>
<OnPlatform x:Key="Material" x:TypeArguments="x:String">
<On Platform="iOS" Value="Material Design Icons" />
<On Platform="Android" Value="materialdesignicons-webfont.ttf#Material Design Icons" />
</OnPlatform>
<Style x:Key="MaterialIcons" TargetType="{x:Type Label}">
<Setter Property="FontFamily" Value="{DynamicResource Material}" />
<Setter Property="FontSize" Value="400" />
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="VerticalOptions" Value="Center" />
<Setter Property="FontSize" Value="Large" />
</Style>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<Label x:Name="label" ></Label>
</StackLayout>
</ContentPage.Content>
And set the Text in code behind.
label.Text = "\ue87e";

I can't change the color of text on the Xamarin Forms Shell

If I use dark mode on my smartphone black color stays white only becomes more saturated. The black and white images are displayed in negative. I tried changing the code in AppShell.xaml, but nothing worked.
AppShell.xaml
<?xml version="1.0" encoding="UTF-8"?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App.Views"
Title="App"
x:Class="App.AppShell">
<!--
The overall app visual hierarchy is defined here, along with navigation.
https://learn.microsoft.com/xamarin/xamarin-forms/app-fundamentals/shell/
-->
<Shell.Resources>
<ResourceDictionary>
<Style x:Key="BaseStyle" TargetType="Element">
<Setter Property="Shell.BackgroundColor" Value="#0f4057" />
<Setter Property="Shell.ForegroundColor" Value="White" />
<Setter Property="Shell.TitleColor" Value="White" />
<Setter Property="Shell.DisabledColor" Value="#B4FFFFFF" />
<Setter Property="Shell.UnselectedColor" Value="#95FFFFFF" />
<Setter Property="Shell.TabBarForegroundColor" Value="White"/>
<Setter Property="Shell.TabBarUnselectedColor" Value="#95FFFFFF"/>
<Setter Property="Shell.TabBarTitleColor" Value="White"/>
</Style>
<Style TargetType="TabBar" BasedOn="{StaticResource BaseStyle}" />
<Style TargetType="FlyoutItem" BasedOn="{StaticResource BaseStyle}" />
</ResourceDictionary>
</Shell.Resources>
<TabBar>
<ShellContent Title="Text" Icon="icon_feed.pn" Route="Page1" ContentTemplate="{DataTemplate local:Page1}" />
<ShellContent Title="Text" Icon="icon_feed.png" ContentTemplate="{DataTemplate local:Page2}" />
<ShellContent Title="Text" Icon="icon_feed.png" ContentTemplate="{DataTemplate local:Page3}" />
<ShellContent Title="Text" Icon="icon_feed.png" ContentTemplate="{DataTemplate local:Page4}" />
</TabBar>
<!--
If you would like to navigate to this content you can do so by calling
await Shell.Current.GoToAsync("//LoginPage");
-->
<TabBar>
<ShellContent Route="LoginPage" ContentTemplate="{DataTemplate local:LoginPage}" />
</TabBar>
</Shell>
Have you looked at theme support which allows you to define a dark and light theme for your app.
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/theming/system-theme-changes
You can use Application.Current.UserAppTheme = OSAppTheme.Dark; to get the theme of the current user and change it by binding AppThemeBinding.

Xamarin Forms Tabbed Page Trigger properties not working

I'm trying to follow this sample
by using font awesome as icon for the tabbed page and use the triggers to change font color
but when I want to apply the style using font awesome I got an error that Property="IsChecked" does not exist for the target.
I noticed in the sample they are using shells how could I replicate that example using regular tabbed pages?
on the app.XAML I have the following
<OnPlatform x:TypeArguments="x:String"
x:Key="FontAwesomeSolid">
<On Platform="Android"
Value="Font5Solid.otf#Regular" />
<On Platform="iOS"
Value="FontAwesome5Free-Solid" />
</OnPlatform>
<OnPlatform x:TypeArguments="x:String"
x:Key="FontAwesomeRegular">
<On Platform="Android"
Value="Font5Regular.otf#Regular" />
<On Platform="iOS"
Value="FontAwesome5Free-Regular" />
</OnPlatform>
For the tabbed page I have the following
<?xml version="1.0" encoding="utf-8"?>
<TabbedPage x:Name="Tab" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="pages.Views.HomeTabbedPage">
<!--Pages can be added as references or inline-->
<TabbedPage.Resources>
<ResourceDictionary>
<Style TargetType="Tab" x:Key="FollowTab">
<Style.Triggers>
<Trigger TargetType="TabbedPage"
Property="IsChecked" Value="False">
<Setter Property="Icon" >
<Setter.Value>
<FontImageSource FontFamily="{StaticResource FontAwesomeRegular}" Glyph=""/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger TargetType="Tab"
Property="IsChecked" Value="True">
<Setter Property="Icon" >
<Setter.Value>
<FontImageSource FontFamily="{StaticResource FontAwesomeSolid}" Glyph=""/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</TabbedPage.Resources>
<ContentPage Title="sample page" />
</TabbedPage>
To replicate that in a normal TabbedPage you can try these steps:
1 - Create a converter to check TabbedPage.CurrentPage type:
public class SelectedTabTypeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return null;
if (!(value is Page))
throw new ArgumentException("Expected value to be of type " + nameof(Page), nameof(value));
// if value is a NavigationPage check against its RootPage
if (value is NavigationPage navPage)
return navPage.RootPage?.GetType();
return value.GetType();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> throw new NotImplementedException();
}
2 - Add the x:Name attribute to the TabbedPage so we can reference it latter:
<TabbedPage x:Name="MyTabbedPage" ...
3 - Add the converter resource to TabbedPage.Resources:
<TabbedPage.Resources>
<ResourceDictionary>
<converters:SelectedTabTypeConverter x:Key="SelectedTabTypeConverter" />
</ResourceDictionary>
</TabbedPage.Resources>
4 - Add the pages and the DataTriggers:
<TabbedPage.Children>
<!-- Normal page tab default values -->
<views:OnePage Title="Page1">
<views:OnePage.Triggers>
<DataTrigger
TargetType="views:OnePage"
Binding="{Binding Source={x:Reference MyTabbedPage}, Path=CurrentPage, Converter={StaticResource SelectedTabTypeConverter}}"
Value="{x:Type views:OnePage}">
<Setter Property="Title" Value="Page1 Selected" />
</DataTrigger>
</views:OnePage.Triggers>
</views:OnePage>
<!-- NavigationPage tab -->
<NavigationPage Title="Page2">
<x:Arguments>
<views:TwoPage />
</x:Arguments>
<NavigationPage.Triggers>
<DataTrigger
TargetType="NavigationPage"
Binding="{Binding Source={x:Reference MyTabbedPage}, Path=CurrentPage, Converter={StaticResource SelectedTabTypeConverter}}"
Value="{x:Type views:TwoPage}">
<Setter Property="Title" Value="Page2 Selected" />
</DataTrigger>
</NavigationPage.Triggers>
</NavigationPage>
</TabbedPage.Children>

How to change list value on certain position click?

I have a list of products in BindableLayout.
When i click on some product i want to change the value of the Active field and "reload" the list print1.
There is any way to change the values of the list from the xaml?
What is the best approach?
MainPage.xaml.cs
public partial class MainPage : ContentPage
{
public List<ProductStatus> ProductList => getProducts();
public MainPage()
{
InitializeComponent();
this.BindingContext = this;
}
public List<ProductStatus> getProducts()
{
return new List<ProductStatus>
{
new ProductStatus { Id="P13", Name = "Product X", Active = false },
new ProductStatus { Id="P17", Name = "Product Y", Active = false },
new ProductStatus { Id="P21", Name = "Product Z", Active = true },
};
}
}
public class ProductStatus
{
public string Id { get; set; }
public string Name { get; set; }
public bool Active { get; set; }
}
}
MainPage.xaml
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout BindableLayout.ItemsSource="{Binding ProductList}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal" Spacing="1" Padding="20">
<StackLayout.Style>
<Style TargetType="StackLayout">
<Style.Triggers>
<DataTrigger Binding="{Binding Active}" Value="true" TargetType="StackLayout">
<Setter Property="BackgroundColor" Value="#f0f0f0"/>
</DataTrigger>
<DataTrigger Binding="{Binding Active}" Value="false" TargetType="StackLayout">
<Setter Property="BackgroundColor" Value="Transparent"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackLayout.Style>
<Label Text="{Binding Name}"/>
<Label HorizontalOptions="EndAndExpand">
<Label.Style>
<Style TargetType="Label">
<Style.Triggers>
<DataTrigger Binding="{Binding Active}" Value="true" TargetType="Label">
<Setter Property="TextColor" Value="Green"/>
<Setter Property="Text" Value="A"/>
</DataTrigger>
<DataTrigger Binding="{Binding Active}" Value="false" TargetType="Label">
<Setter Property="TextColor" Value="Red"/>
<Setter Property="Text" Value="I"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
<Button Text="Save"/>
</StackLayout>
First if you want to display a list,it's better to use ListView or CollectionView,that's will be more convenient.
If you still want to use BindableLayout here,you could add a TapGestureRecognizer to your StackLayout.And let your ProductStatus implement INotifyPropertyChanged interface(for reload the data).
public partial class MainPage: ContentPage
{
public List<ProductStatus> ProductList => getProducts();
public ICommand TapCommand { get; set; }
public MainPage()
{
InitializeComponent();
TapCommand = new Command<ProductStatus>(OnTapCommand);
this.BindingContext = this;
}
private void OnTapCommand(ProductStatus obj)
{
var product = obj;
product.Active = !obj.Active;
}
public List<ProductStatus> getProducts()
{
return new List<ProductStatus>
{
new ProductStatus { Id="P13", Name = "Product X", Active = false },
new ProductStatus { Id="P17", Name = "Product Y", Active = false },
new ProductStatus { Id="P21", Name = "Product Z", Active = true },
};
}
}
public class ProductStatus :INotifyPropertyChanged
{
public string Id { get; set; }
public string Name { get; set; }
private bool active;
public bool Active {
set
{
active = value;
OnPropertyChanged("Active");
}
get
{
return active;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
in your xaml (set x:Name to your contentpage,then binding its command):
<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"
mc:Ignorable="d"
x:Name="root"
x:Class="EntryCa.MainPage">
<ContentPage.Content>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout BindableLayout.ItemsSource="{Binding ProductList}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal" Spacing="1" Padding="20">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.TapCommand,Source ={x:Reference root} }"
CommandParameter="{Binding .}"></TapGestureRecognizer>
</StackLayout.GestureRecognizers>
<StackLayout.Style>
<Style TargetType="StackLayout">
<Style.Triggers>
<DataTrigger Binding="{Binding Active}" Value="true" TargetType="StackLayout">
<Setter Property="BackgroundColor" Value="#f0f0f0"/>
</DataTrigger>
<DataTrigger Binding="{Binding Active}" Value="false" TargetType="StackLayout">
<Setter Property="BackgroundColor" Value="Transparent"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackLayout.Style>
<Label Text="{Binding Name}"/>
<Label HorizontalOptions="EndAndExpand">
<Label.Style>
<Style TargetType="Label">
<Style.Triggers>
<DataTrigger Binding="{Binding Active}" Value="true" TargetType="Label">
<Setter Property="TextColor" Value="Green"/>
<Setter Property="Text" Value="A"/>
</DataTrigger>
<DataTrigger Binding="{Binding Active}" Value="false" TargetType="Label">
<Setter Property="TextColor" Value="Red"/>
<Setter Property="Text" Value="I"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
<Button Text="Save"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
the effect like:

Using Pivot.ItemTemplate to avoid replication

The following XAML works OK:
<Page ...
<Page.Resources>
<SolidColorBrush x:Key="brushHeaderBkgr" Color="Blue" />
<SolidColorBrush x:Key="brushContentBorder" Color="Aquamarine" />
<SolidColorBrush x:Key="brushContentBkgr" Color="Blue" />
<SolidColorBrush x:Key="brushContentList" Color="Red" />
<Style TargetType="Border" x:Key="ContentFrame">
<Setter Property="BorderBrush" Value="{StaticResource brushContentBorder}" />
<Setter Property="BorderThickness" Value="6" />
<Setter Property="Padding" Value="6" />
<Setter Property="Background" Value="{StaticResource brushContentBkgr}" />
</Style>
<Style TargetType="ListView" x:Key="ContentList" >
<Setter Property="Background" Value="{StaticResource brushContentList}" />
</Style>
</Page.Resources>
<Grid>
<Pivot Title="Whatever" Margin="10">
<PivotItem Header="Header1" >
<Border Style="{StaticResource ContentFrame}">
<ListView x:Name="Content" Style="{StaticResource ContentList}" />
</Border>
</PivotItem>
<PivotItem Header="Header2" >
<Border Style="{StaticResource ContentFrame}">
<ListView x:Name="Content" Style="{StaticResource ContentList}" />
</Border>
<PivotItem Header="Header3" >
<Border Style="{StaticResource ContentFrame}">
<ListView x:Name="Content" Style="{StaticResource ContentList}" />
</Border>
</Pivot>
</Grid>
</Page>
Since all item pages have same structure, I wanted to avoid replication by using Pivot.ItemTemplate. Here is the modified XAML:
<Page ...
<Page.Resources>
<SolidColorBrush x:Key="brushHeaderBkgr" Color="Blue" />
<SolidColorBrush x:Key="brushContentBorder" Color="Aquamarine" />
<SolidColorBrush x:Key="brushContentBkgr" Color="Blue" />
<SolidColorBrush x:Key="brushContentList" Color="Red" />
<Style TargetType="Border" x:Key="ContentFrame">
<Setter Property="BorderBrush" Value="{StaticResource brushContentBorder}" />
<Setter Property="BorderThickness" Value="6" />
<Setter Property="Padding" Value="6" />
<Setter Property="Background" Value="{StaticResource brushContentBkgr}" />
</Style>
<Style TargetType="ListView" x:Key="ContentList" >
<Setter Property="Background" Value="{StaticResource brushContentList}" />
</Style>
</Page.Resources>
<Grid>
<Pivot Title="Whatever" Margin="10">
<Pivot.ItemTemplate>
<DataTemplate>
<Border Style="{StaticResource ContentFrame}">
<ListView x:Name="Content" Style="{StaticResource ContentList}" />
</Border>
</DataTemplate>
</Pivot.ItemTemplate>
<PivotItem Header="Header1" />
<PivotItem Header="Header2" />
<PivotItem Header="Header3" />
</Grid>
</Page>
However this doesn't work, the items don't appear. Why?
You can't set ItemTemplate and add PivotItems in this way. You need to add the data source to the pivot via the ItemSource and use binding in your item templates.
Look at this code.
MainPage.xaml:
<Pivot x:Name="Pivot" Title="Whatever" Margin="10">
<Pivot.ItemTemplate>
<DataTemplate>
<Border Style="{StaticResource ContentFrame}">
<ListView ItemsSource="{Binding ListViewSource}" Style="{StaticResource ContentList}" />
</Border>
</DataTemplate>
</Pivot.ItemTemplate>
<Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}"/>
</DataTemplate>
</Pivot.HeaderTemplate>
</Pivot>
MainPage.xaml.cs:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
List<PivotModel> items = new List<PivotModel>();
items.Add(new PivotModel() { Header = "Header1", ListViewSource = Enumerable.Range(10, 10).ToList() });
items.Add(new PivotModel() { Header = "Header2", ListViewSource = Enumerable.Range(20, 10).ToList() });
items.Add(new PivotModel() { Header = "Header3", ListViewSource = Enumerable.Range(30, 10).ToList() });
items.Add(new PivotModel() { Header = "Header4", ListViewSource = Enumerable.Range(40, 10).ToList() });
Pivot.ItemsSource = items;
}
PivotModel.cs:
public class PivotModel
{
public string Header { get; set; }
public List<int> ListViewSource { get; set; }
}