Styling Label inside another control - xaml

In Xamarin Forms, having a XAML code: (an example below) is it possible to move the style of the Label and the Image to appplication level style and make it default for all Expander headers (or other containers)?
<xct:Expander>
<xct:Expander.Header>
<StackLayout>
<Label
Margin="20,10,0,10"
FontAttributes="Bold"
HorizontalOptions="StartAndExpand"
Text="ABCD"
TextTransform="Uppercase"
VerticalOptions="Center" />
<Image
Margin="0,0,20,0"
HorizontalOptions="End"
VerticalOptions="Center">
<Image.Source>
<FontImageSource
FontFamily="{StaticResource Font_FASolid}"
Glyph="{x:Static fonts:FASolid.ChevronDown}"
Size="{StaticResource MediumFontSize}" />
</Image.Source>
</Image>
</StackLayout>
</xct:Expander.Header>
</xct:Expander>
What I would like to have in my xaml finally is just:
<xct:Expander>
<xct:Expander.Header>
<StackLayout>
<Label Text="ABCD"/>
<Image>
<Image.Source>
<FontImageSource/>
</Image.Source>
</Image>
</StackLayout>
</xct:Expander.Header></xct:Expander>

Related

Xamarin forms listview items not fully shown

I have this Xamarin listview:
<ContentPage.Content>
<ScrollView>
<StackLayout Padding="20,20,20,20">
<Grid>
<StackLayout Margin="10">
<Label Text="Quoting and Tankering" Style="{DynamicResource TitleStyle}" Margin="0, 20" HorizontalTextAlignment="Center" />
<Label Text="Select Aircraft:" />
<Picker Margin="30, 0, 0, 30" x:Name="pickerAircraft" ItemDisplayBinding="{Binding TailNumber}" SelectedItem="{Binding Id}" SelectedIndexChanged="PickerAircraft_SelectedIndexChanged" Title="Aircraft Selector"></Picker>
<Button Text="Add Leg" Margin="10,10,10,10" TextColor="Green" Clicked="Button_Clicked_1" />
<ListView ItemsSource="{Binding .}" VerticalOptions="Center">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10,10,10,10" HeightRequest="100">
<Label Text="Leg" />
<StackLayout Orientation="Horizontal" HeightRequest="100">
<Entry x:Name="txtICAO" WidthRequest="30" Text="{Binding ICAO}" />
<Button Text="Delete" WidthRequest="50" Clicked="Button_Clicked_2" x:Name="btn_Delete_Item_In_Cart" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Text="Go to Step 2"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center"
Clicked="Button_Clicked" />
</StackLayout>
</Grid>
</StackLayout>
</ScrollView>
</ContentPage.Content>
Now, when I'm rendering the page the listview items are partially shown, please check the screenshot:
What am I doing wrong with the listview? Do I need to add some margin/padding in order to have the full size shown?
Also the button below the listview is not shown.

Placing UI elements "on top of each other" using FlexLayout in Xamarin.Forms

My goals:
Place an Editor inside of a Frame, and the editor never expand outside of the frame, no matter how much text is supplied.
Place an ActivityIndicator 'inside' a Button (and make the Button text not visible when IsBusy).
Make it relative for different sized devices.
My questions
Is there a way to make these controls appear 'on top' of each other using FlexLayout?
Could there be another, more appropriate, layout for my problem?
Current setup:
What I'd like it to look like:
The current XAML
<!-- This is where the main content on the slide up menu starts -->
<Frame
Grid.Row="1"
BorderColor="white"
CornerRadius="0"
HasShadow="True"
OutlineColor="White">
<FlexLayout
AlignItems="Center"
Direction="Column"
JustifyContent="SpaceEvenly">
<!-- Title -->
<Label
Grid.Row="0"
FontAttributes="Bold"
FontSize="Medium"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
Text="{util:Translate Viewtitle}" />
<!-- Scrollable text -->
<ScrollView
x:Name="ActionViewScroller"
Grid.Row="1"
Margin="10"
HorizontalOptions="Fill"
VerticalOptions="Center"
VerticalScrollBarVisibility="Always">
<Label Text="{Binding ActionText}" />
</ScrollView>
<!-- Text box for optional notes -->
<Frame
Grid.Row="2"
Margin="10"
BackgroundColor="White"
BorderColor="LightGray"
CornerRadius="0"
FlexLayout.Gorw="1"
HasShadow="False"
WidthRequest="280" />
<Editor
x:Name="ActionViewNotes"
Grid.Row="2"
Margin="15"
AutoSize="TextChanges"
FlexLayout.Grow="1"
HorizontalOptions="FillAndExpand"
IsSpellCheckEnabled="True"
Keyboard="Default"
MaxLength="150"
Placeholder="{util:Translate PlaceholderText}"
Text="{Binding ConsentNotes, Mode=OneWayToSource}"
VerticalOptions="Center"
WidthRequest="280" />
<!-- Submit Button -->
<Button
Grid.Row="3"
AlignSelf="Stretch"
Command="{Binding DoSomething}"
CommandParameter="{Binding Source={Reference TheNotes}, Path=Text}"
HeightRequest="70"
HorizontalOptions="FillAndExpand"
IsVisible="{Binding IsBusy, Converter={StaticResource NegateBooleanConverter}}"
Style="{StaticResource TertiaryButtonStyle}"
Text="{util:Translate DoSomethingText}"
WidthRequest="350" />
<ActivityIndicator
Grid.Row="3"
Margin="5"
HorizontalOptions="Center"
IsRunning="{Binding IsBusy}"
IsVisible="{Binding IsBusy}"
Style="{DynamicResource BaseActivityIndicatorStyle}" />
</FlexLayout>
</Frame>
1.Is there a way to make these controls appear 'on top' of each other using FlexLayout?
Yes, you can put the editor on top of Frame in your case. It is the same as you put a Frame inside a Flexlayout. I added some backgroundColor to the controls to make it clear.
Here is a example of put the editor inside Frame:
<StackLayout>
<!-- Place new controls here -->
<Frame
Grid.Row="1"
BorderColor="white"
CornerRadius="0"
HasShadow="True"
OutlineColor="White">
<FlexLayout
AlignItems="Center"
Direction="Column"
JustifyContent="SpaceEvenly">
<!-- Title -->
<Label
Grid.Row="0"
FontAttributes="Bold"
FontSize="Medium"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
BackgroundColor="Green"
Text=" Viewtitle" />
<!-- Scrollable text -->
<ScrollView
x:Name="ActionViewScroller"
Grid.Row="1"
Margin="10"
HorizontalOptions="Fill"
VerticalOptions="Center"
VerticalScrollBarVisibility="Always">
<Label Text="123" />
</ScrollView>
<!-- Text box for optional notes -->
<Frame
Grid.Row="2"
Margin="10"
BorderColor="LightGray"
CornerRadius="0"
FlexLayout.Grow="1"
HasShadow="False"
WidthRequest="280"
BackgroundColor="Red">
<!-- Put your Editor inside Frame here -->
<Editor
x:Name="ActionViewNotes"
Grid.Row="2"
Margin="15"
AutoSize="TextChanges"
FlexLayout.Grow="1"
HorizontalOptions="FillAndExpand"
IsSpellCheckEnabled="True"
Keyboard="Default"
MaxLength="150"
Placeholder="PlaceholderText"
VerticalOptions="Center"
WidthRequest="280"
BackgroundColor="AliceBlue"/>
</Frame>
</FlexLayout>
</Frame>
</StackLayout>
2.Could there be another, more appropriate, layout for my problem?
There are several ways to achieve the layout for your problem. You can use StackLayout,AbsoluteLayout,RelativeLayout,Grid and so on. In my opinion, which to choose depending on yourself. Each way has its own advantages. Flexlayout is more conveniently to arrange its children horizontally and vertically in a stack.
You can refer to the official documents about layout.There are several demos similar with your layout and you can get the advantages of each layout option from there.
Layouts

Bind BackgroundColor of a view inside DataTemplate Xamarin.Forms

I have a list view with a DataTemplate and inside it I have a StackLayout that I need set its background but the color of it is inside a variable...When I programmatically set the background of an object using this variable color it works, but when I try to use "binding" in xaml it doesn't work and I can't get this stack programmatically because it's inside a data template...
I really need your answer..
Some help?
<ListView.ItemTemplate>
<DataTemplate>
<!--<DataTemplate.Triggers>
<DataTrigger Binding="{Binding fundoColor}" Value="4">
<Setter TargetName="produtos_stack_color" Property="Background" Value="LawnGreen" />
</DataTrigger>
</DataTemplate.Triggers>-->
<ViewCell>
<StackLayout x:Name="produtos_stack_color" BackgroundColor="{Binding fundoColor}" VerticalOptions="FillAndExpand" Margin="10,10,10,10">
<StackLayout Orientation="Horizontal" Padding="10,10,10,10" BackgroundColor="Black" HorizontalOptions="FillAndExpand">
<Image Source="{Binding imagem}" HeightRequest="80" HorizontalOptions="CenterAndExpand" WidthRequest="160" Aspect="Fill"/>
<StackLayout Orientation="Horizontal" BackgroundColor="Green" VerticalOptions="Center" HorizontalOptions="CenterAndExpand">
<Label Style="{StaticResource labelsfont}" Text="R$" FontSize="Medium" TextColor="White"/>
<Label Style="{StaticResource labelsfont}" Text="{Binding valor}" FontAttributes="Bold" FontSize="Large" TextColor="White"/>
</StackLayout>
</StackLayout>
<StackLayout Margin="0,0,0,10">
<Label Text="{Binding nome}" Style="{StaticResource labelsfont}" FontAttributes="Bold" FontSize="Medium" TextColor="White" VerticalOptions="StartAndExpand" HorizontalOptions="Center"/>
<ContentView BackgroundColor="Chartreuse" HorizontalOptions="FillAndExpand">
<Label Style="{StaticResource labelsfont}" Text="{Binding observacao}" TextColor="White" Margin="10,10,10,10" HorizontalOptions="Center" />
</ContentView>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
I heard about triggers...but I really don't know how it works exactly...
I need produtos_stack_color receive the color
My global variable in code behind...It is setted just in construct of my class
InitializeComponent();
fundoColor = Color.FromHex(this.categEscolhida.corFundo);
You can only bind with properties - so you will have to create a property in code-behind class.
public Color FundoColor { get { return fundoColor; } }
Secondly, in order to refer this property in XAML - you can use Reference extension, and specify parent as Source. For e.g.:
<StackLayout x:Name="produtos_stack_color"
BackgroundColor="{Binding FundoColor, Source={x:Reference ParentHost}}" ..>
And, make sure to set x:Name attribute in root node of your XAML. For e.g:
<ContentPage x:Name="ParentHost" .. />

How to change icon color in Xamarin.Forms xaml page?

Currently, I am developing a Xamarin.Forms PCL application for Android and iOS. In one of my pages I define a ListView. The template for the ListView.ItemTemplate displays an icon using <Image Source="some_Icon.png" />. The icon displays as expected (black) but I have not found a way to set the color.
I would like to colorize this icon based on logic in my ViewModel.
I have searched for answers both through the Documentation and StackOverlflow to no avail.
Is there a better way to display and style icons from a Xamarin.Forms PCL project?
Does Xamarin.Forms require a set of resource/image files for every possible color I might use?
I solved my problem with Iconize for Xamarin.Forms. I implemented my solution based off the Iconize sample code below.
<?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:iconize="clr-namespace:FormsPlugin.Iconize;assembly=FormsPlugin.Iconize"
x:Class="Iconize.FormsSample.Page1"
Title="{Binding FontFamily}">
<ContentPage.ToolbarItems>
<iconize:IconToolbarItem Command="{Binding ModalTestCommand}" Icon="fa-500px" />
<iconize:IconToolbarItem Command="{Binding VisibleTestCommand}" Icon="fa-500px" IconColor="Red" />
<iconize:IconToolbarItem Command="{Binding VisibleTestCommand}" Icon="fa-500px" IsVisible="{Binding VisibleTest}" />
</ContentPage.ToolbarItems>
<ListView CachingStrategy="RecycleElement" ItemsSource="{Binding Characters}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<iconize:IconImage HeightRequest="20" Icon="{Binding Key}" IconColor="Blue" WidthRequest="20" />
<iconize:IconImage HeightRequest="20" Icon="{Binding Key}" BackgroundColor="Blue" IconColor="Yellow" WidthRequest="20" IconSize="10" />
<iconize:IconButton FontSize="20" Text="{Binding Key}" TextColor="Red" WidthRequest="48" />
<iconize:IconLabel FontSize="20" Text="{Binding Key}" TextColor="Green" VerticalTextAlignment="Center" />
<Label Text="{Binding Key}" VerticalTextAlignment="Center" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
In my case, I simply had to replace my original <Image .../> element and replace it with
<iconize:IconImage HeightRequest="20" Icon="fa-circle" IconColor="{Binding CircleColor}" WidthRequest="20" />.
In my ViewModel, I added the CircleColor property to set the icon color as needed based on my logic.

Xamarin - slide element within Frame outside of view

Not really sure how to properly describe my problem using correct wording as I'm new to Xamarin and Xaml.
I have a Frame with several StackLayouts within and I want to slide a specific StackLayout outside the Frame without showing it outside the Frame.
I can currently do this with:
XAML:
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:XLabs.Forms.Controls;assembly=XLabs.Forms"
xmlns:mr="clr-namespace:MR.Gestures;assembly=MR.Gestures"
x:Class="iRemote.UI.Maps.LocationFinderMap"
xmlns:map="clr-namespace:iRemote.Location"
Title="Location Finder">
<Frame HasShadow="true" OutlineColor="Color.Black" WidthRequest="700" HeightRequest="300" Padding="3"
BackgroundColor="White">
<mr:StackLayout x:Name="sl_main" Padding="2" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
Orientation="Horizontal" WidthRequest="200">
<StackLayout HorizontalOptions="Start" Orientation="Vertical">
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<Label Text="Parcel #" />
<Entry x:Name="txtParcel" WidthRequest="100" />
<Label HorizontalOptions="FillAndExpand" />
<Button x:Name="btnClose" BackgroundColor="#0786a3" BorderRadius="30" TextColor="White"
Text="Close" HorizontalOptions="End" />
</StackLayout>
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<Label Text="Meter #" />
<Entry x:Name="txtMeter" WidthRequest="100" />
</StackLayout>
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<SearchBar x:Name="search" Placeholder="Search" />
</StackLayout>
<StackLayout Padding="2" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout HorizontalOptions="FillAndExpand">
<mr:Image x:Name="img_map" Source="down" HeightRequest="19" WidthRequest="32" />
</StackLayout>
</StackLayout>
</StackLayout>
<StackLayout x:Name="sl_map" Padding="2" HorizontalOptions="FillAndExpand" HeightRequest="5"
VerticalOptions="FillAndExpand" IsVisible="true" WidthRequest="300">
<map:ExtendedMap
BackgroundColor="Blue"
x:Name="MP"
IsShowingUser="true"
MapType="Street" />
</StackLayout>
</mr:StackLayout>
</Frame>
</ContentPage>
Code-Behind:
if (panelShowing)
{
var rect = new Rectangle(this.Width - sl_map.Width, sl_map.Y, sl_map.Width, sl_map.Height);
sl_map.LayoutTo(rect, 250, Easing.CubicIn);
}
else
{
var rect = new Rectangle(this.Width + sl_map.Width - 40, sl_map.Y, sl_map.Width, sl_map.Height);
sl_map.LayoutTo(rect, 200, Easing.CubicOut);
}
However, sl_map simply just shows outside the frame. I want it to not be visible as it crosses the border of the frame. I hope that's clear enough. Again, sorry if I'm not using the correct terminology. I'm a WinForms guy.