I created a shell project, and in the app.xaml I created a control template with a label inside which I have to assign the value of a variable as text, but I can't do it from the cs, any suggestions?
The label to which I have to assign the value is set like this
<ControlTemplate x:Key="HeaderFooterTemplate">
<StackLayout BackgroundColor="#373B53" Spacing="0">
<Label x:Name="utente" Padding="10, 0, 0, 0" Text="Utente" FontSize="Large" TextColor="White" LineBreakMode="TailTruncation" VerticalOptions="Center" />
<ContentPresenter/>
</StackLayout>
</ControlTemplate>
Related
I'm trying to achieve dynamic row height in CollectionView control, so that when ever I have more text for a particular property it will extend the height of the frame automatically.
I have tried with ListView as well using HasUnEvenRow property "true" but with that also it's not working.
Here is my code:
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Grid RowDefinitions="*,60" BackgroundColor="{StaticResource PageBackgroundColor}" Padding="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<CollectionView Grid.Row="0" HorizontalOptions="Fill" VerticalOptions="Fill"
ItemsSource="{Binding Inspections}"
VerticalScrollBarVisibility="Always"
ItemsLayout="VerticalList" ItemSizingStrategy="MeasureAllItems">
<CollectionView.ItemTemplate>
<DataTemplate>
<Frame Padding="15" HasShadow="False">
<Grid HorizontalOptions="Fill"
VerticalOptions="Fill"
BackgroundColor="White"
RowSpacing="25"
RowDefinitions="Auto,Auto,Auto"
ColumnDefinitions="*,Auto">
<StackLayout
Orientation="Horizontal"
Grid.Row="0"
Grid.Column="0">
<Label Text="{Binding Path=BusinessName}"
Style="{StaticResource LabelTitleStyle}" />
<Grid Padding="15,0,0,0">
<baseChip:Chip
HorizontalOptions="Fill" VerticalOptions="Fill"
Style="{StaticResource ChipContainer}"
HasShadow="False"
BackgroundColor="{Binding Path=ChipBackgroundColor}">
</baseChip:Chip>
<Label
Text="{Binding Path=ChipText}"
Style="{StaticResource ChipLabel}"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"
TextColor="{Binding Path=ChipTextColor}"/>
</Grid>
</StackLayout>
<Image
Grid.Row="0"
Grid.Column="1"
HorizontalOptions="End"
VerticalOptions="Center"
Aspect="AspectFit">
<Image.Source>
<FontImageSource Glyph="{x:Static helper:MaterialFontHelper.FilePdfBox}"
Color="{StaticResource DarkGray}"
Size="20"
FontFamily="MaterialDesignIcons"/>
</Image.Source>
</Image>
<Grid Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
RowDefinitions="Auto, Auto"
ColumnDefinitions="*, *">
<Label
Grid.Row="0"
Grid.Column="0"
Text="Inspection Type"
Style="{StaticResource LabelKeyStyle}" />
<Label
Grid.Row="1"
Grid.Column="0"
Text="ksd kahdkahd kahd kahd aojsoiud aasjlj sdlkja dlkja da asdadas alsajdlaksjdlajd alsjdalkjd alksjd sa"
Style="{StaticResource LabelValueStyle}" />
<Label
Grid.Row="0"
Grid.Column="1"
Text="Primary Inspector"
Style="{StaticResource LabelKeyStyle}" />
<Label
Grid.Row="1"
Grid.Column="1"
Style="{StaticResource LabelValueStyle}" >
<Label.FormattedText>
<FormattedString>
<Span Text="{Binding Path=InspectorFirstName}"/>
<Span Text=" "/>
<Span Text="{Binding Path=InspectorLastName}"/>
</FormattedString>
</Label.FormattedText>
</Label>
</Grid>
<Grid Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2"
RowDefinitions="*, *"
ColumnDefinitions="*, *">
<Label
Grid.Row="0"
Grid.Column="0"
Text="Scheduled Date"
Style="{StaticResource LabelKeyStyle}" />
<Label
Grid.Row="1"
Grid.Column="0"
Text="{Binding Path=ScheduledStartDate, Converter={StaticResource dateFormatter},ConverterParameter='long'}"
Style="{StaticResource LabelValueStyle}" />
<Label
Grid.Row="0"
Grid.Column="1"
Text="Completed Date"
Style="{StaticResource LabelKeyStyle}" />
<Label
Grid.Row="1"
Grid.Column="1"
Text="{Binding Path=CompletionDate, Converter={StaticResource dateFormatter},ConverterParameter='long'}"
Style="{StaticResource LabelValueStyle}" />
</Grid>
</Grid>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<StackLayout
Grid.Row="1"
VerticalOptions="End"
HorizontalOptions="FillAndExpand"
BackgroundColor="{StaticResource White}">
<controlTemplate:BeginInspectionContentView></controlTemplate:BeginInspectionContentView>
</StackLayout>
</Grid>
</StackLayout>
Output & expected output image attached here:
How to achieve dynamic height for this UI? Any help or suggestions are welcome.
There are three solutions to this problem:
You can change CollectionView to FlexLayout with BindableLayout.ItemsSource and BindableLayout.ItemTemplate. Then you don't need to set Height for item or FlexLayout because all are dynamic.
You can set a value to collectionView.HeightRequest using MVVM. When item increase, the height will increase as well. For more details about this solution, you may refer to the link.
You can use CollectionView.Behaviors to calculate the Height of every item to increase the height of ContentView. For more details about this solution, you may refer to the link.
You have Grid. With StackLayout. With Grid. With Small Grids inside it.
I will put aside for now, that this is extremely bad for rendering. (It is serious problem however...)
None of the expected output justify this organization.
If you need for element to occupy 2 columns, you can use columns span 2.
Before anything else, please combine all 4 grids in a single grid.
After you are done with that, limit your VisualElements height, or, even better, limit the content you are putting in them. (Because cut content looks bad. You should be using something like "show more" link, that opens popup or whatever).
If you have any questions, please ask.
Edit: Let me clarify:
You have the same Grid code. Most important part - columns are * , * , and rows are auto height. And every 2 rows, you create another GRID, that is copy of the first GRID.
This is extremely counterproductive.
Also, just because you can do something, and it is "working in xamarin", it doesn't mean that you should do it.
First, put everything in the same grid, instead of nesting it and copying grids, then you can start working on CLIP/Height limit/etc.
(Recommending you to test it on IOS, because once you get it running fine there, it is much easier to fine-tune it for other platforms, than the other way around.)
A grid cell looks like this:
<Label Text="{Binding Name}"
Grid.Row="0"
Grid.Column="1"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
FontSize="16"
TextColor="White"
BackgroundColor="red" />
There are 2 columns, and each column is 50% of the width. With the xaml above, the whole cell (half the row) will be painted red.
It looks like this:
Can I add left and/or right padding just to Grid.Row="0" and Grid.Column="1" so that the column is still 50% width but not the label? What I don't want to do is change the grid structure (ie. add more columns).
The desired result is something like this, but without having to add more columns or change column size:
Just add HorizontalOptions="Center" if you just want to place in the middle of the column. In this method, if the label's text is increased, the space around the label decreases.
If you want to have a certain amount of space around the label, you should set Margin for Label.
<Label Text="{Binding Name}"
Grid.Row="0"
Grid.Column="1"
Margin="20,0"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
FontSize="16"
TextColor="White"
BackgroundColor="red" />
You can put the label in a StackLayout and set the padding of it.Such as:
<StackLayout Grid.Row="0" Grid.Column="1" Padding="10,0,10,0">
<Label
Text="text"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
FontSize="16"
TextColor="White"
BackgroundColor="red" />
</StackLayout>
PS:Differernt from padding in CSS (top-right-buttom-left),the order of the padding in xamarin is left-top-right-buttom.
For more detail you can refer Margin and Padding
If I understood that correctly you need margin and not padding. For the very same reason, you won't find a padding property in Label, like many other views in Xamarin Forms.
This should serve your purpose.
<Label Text="{Binding Name}"
Grid.Row="0"
Grid.Column="1"
Margin="20, 0, 20, 0"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
FontSize="16"
TextColor="White"
BackgroundColor="red" />
To understand how padding and margin works in details, you can check this link
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/layouts/margin-and-padding
Here is the XAML code that I created:
<ViewCell>
<Grid VerticalOptions="CenterAndExpand" Padding="20, 0">
<Label HorizontalOptions="StartAndExpand" Text="ABC" />
<Entry Keyboard="Numeric" VerticalOptions="Center" HorizontalOptions="End" />
</Grid>
</ViewCell>
When I run the code the data entry area for the window is only wide enough to show one digit. Is there a way I can expand this so it will allow me to enter three digits?
Set a WidthRequest value, and also try changing the HorizontalOptions
<Entry Keyboard="Numeric" VerticalOptions="Center" WidthRequest="100" HorizontalOptions="FillAndExpand" />
I have this code:
<ViewCell x:Name="ss" Height="50">
<Grid VerticalOptions="CenterAndExpand" Padding="20, 0">
<Label Style="{DynamicResource ListItemTextStyle}" HorizontalOptions="StartAndExpand" VerticalOptions="Center" Text="Category Group" />
<Switch x:Name="ssSwitch" HorizontalOptions="End" VerticalOptions="Center" Grid.Column="1" Toggled="SsSwitch" />
</Grid>
</ViewCell>
I would like to extend this with another row and a label with the text of "Clear Deck"
How can I add a label for this that when clicked will call a method?
Here's a simple example of how to do it. You just need to add a Label with a TapGestureRecognizer. Then you need to implement ClearLabelTapped in the code behind.
<ViewCell x:Name="ss" Height="50">
<StackLayout Orientation="Vertical">
<Grid VerticalOptions="CenterAndExpand" Padding="20, 0">
<Label Style="{DynamicResource ListItemTextStyle}" HorizontalOptions="StartAndExpand" VerticalOptions="Center" Text="Category Group" />
<Switch x:Name="ssSwitch" HorizontalOptions="End" VerticalOptions="Center" Grid.Column="1" Toggled="SsSwitch" />
</Grid>
<Label Text="Clear Deck">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="ClearLabelTapped" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
</ViewCell>
Code behind:
public void ClearLabelTapped(object sender, EventArgs args)
{
// This is called when you tab the "Clear Deck" label
}
Please notice that using view models and commands would be a better way to do this (separation of concerns) but I wanted to keep this simple. Refer to the official documentation on how to work with the TapGestureRecognizer.
I am trying to make a label wrap inside of the Master page of a MasterDetail page. I thought it was the default behavior to wrap labels, but just in case I even made a custom renderer. I have confirmed that the custom renderer works (through debugging and adding a background to the label), so I assume there is something easy that I am missing. Can anybody take a look at my xaml and give me an idea why this label is not wrapping?
<?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="MyApp.Pages.NavigationDrawer.NavigationMenuMasterPage"
xmlns:statics="clr-namespace:MyApp.Statics;assembly=MyApp"
xmlns:multi="clr-namespace:MyApp.Pages.NavigationDrawer;assembly=MyApp"
Title="Navigation drawer"
Icon="hamburger.png"
BackgroundColor="White">
<ContentPage.Content>
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="Center" Margin="0, 25, 0, 0">
<StackLayout Orientation="Horizontal" HorizontalOptions="Center">
<Image x:Name="connectionStatusImage" />
<Label x:Name="connectionStatusText" Margin="16, 0, 16, 0" YAlign="Center" FontSize="Medium"/>
</StackLayout>
<Label x:Name="changeConnectionStatusButton" TextColor="{x:Static statics:Palette.Orange}" XAlign="Center" FontAttributes="Bold" >
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="ChangeConnectionStatusClicked" NumberOfTapsRequired="1" />
</Label.GestureRecognizers>
</Label>
<StackLayout x:Name="SyncStatusStack" Orientation="Horizontal" Margin="0, 16, 16, 0" VerticalOptions="Center" >
<multi:MultiLineLabel x:Name="syncStatusText" MinimumWidthRequest="0" Margin="16, 0, 0, 0" Text="I want to write a really long string to see if it wraps" />
<Label x:Name="syncButton" MinimumWidthRequest="40" Text="SYNC" FontAttributes="Bold" YAlign="Center" HorizontalOptions="End" >
<Label.GestureRecognizers>
<TapGestureRecognizer x:Name="SyncGestureRecognizer" NumberOfTapsRequired="1" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
<StackLayout x:Name="SyncStack" Orientation="Vertical" HorizontalOptions="Center" Margin="0, 16, 0, 0">
<ActivityIndicator x:Name="syncingIndicator" Margin="16, 0, 32, 0"/>
<Label x:Name="syncingText" />
</StackLayout>
<ListView x:Name="menuListView" VerticalOptions="FillAndExpand" SeparatorVisibility="None" Margin="0, 16, 0, 0">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Title}" TextColor="{x:Static statics:Palette.PrimaryText}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
And my (most likely unnecessary) custom label renderer:
using MyApp.iOS.Renderers;
using MyApp.Pages.NavigationDrawer;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(MultiLineLabel), typeof(MultiLineLabeliOSRenderer))]
namespace MyApp.iOS.Renderers
{
public class MultiLineLabeliOSRenderer : LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (Control == null) return;
Control.LineBreakMode = UIKit.UILineBreakMode.WordWrap;
Control.Lines = 0;
}
}
}
Hmm not sure why, but you are correct setting lines to 0 and using word wrap should do the trick ( Multiple lines of text in UILabel )
I recently also implemented this with a custom renderer ( http://depblog.weblogs.us/2016/06/27/xamarin-forms-multi-line-label-custom-renderer-gotcha/ ) and used a number to indicate the exact amount of lines I would like to have.
That is being set into the Lines property and then the wrapping works.