Xamarin.Forms: can grid cell include several labels? - xamarin

One of the grid cells looks like this:
<Label Text="{Binding Address1}" FontSize="12" TextColor="Black" Grid.Row="1" Grid.Column="0"/>
This displays Address1 which is correct.
But instead of just showing Address1, I would like to display Address1, City, St, each with a different FontSize.
Can this be done without altering the number of rows and columns in the grid?

One way is to place a StackLayout at the Grid row|column and then separately format each element within it:
<Grid....
~~~
<StackLayout Grid.Row="1" Grid.Column="0">
<Label Text="{Binding Address1}" FontSize="12" TextColor="Black" />
<StackLayout Orientation="Horizontal" >
<Label Text="{Binding City}" FontSize="10" TextColor="Black" />
<Label Text="{Binding St}" FontSize="10" TextColor="Black" />
</StackLayout>
<StackLayout>
~~~
</Grid>

Sure, you would use:
<StackLayout Grid.Row="1" Grid.Column="0">
<Label Text="l1"/>
<Label Text="l2"/>
<Label Text="l3"/>
</StackLayout>

You can use other layouts such as StackLayout inside of your Grid as others suggested but you can also put multiple Views inside a Grid cell by setting the same Grid.Row and Grid.Column for them and by setting HorizontalOptions and VerticalOptions of views inside the Grid you can choose each view position.
For Example:
<Grid....
~~~
<Label Grid.Row="0" Grid.Column="1" HorizontalOptions="Start" VerticalOptions="Start" Text="{Binding Address1}" FontSize="12" TextColor="Black" />
<Label Grid.Row="0" Grid.Column="1" HorizontalOptions="Start" VerticalOptions="End" Text="{Binding City}" FontSize="10" TextColor="Black" />
<Label Grid.Row="0" Grid.Column="1" HorizontalOptions="End" VerticalOptions="End" Text="{Binding St}" FontSize="10" TextColor="Black" />
~~~
</Grid>

Related

How to make Grid Row dynamic in CollectionView control of .Net MAUI?

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.)

Xamarin - ImageButton doesnt activate every click

Screen
On the picture above you can see where the ImageButton sometimes activates. When I spam clicking in the blue area the counter sometimes increases. I think there might be another Layer on top of the ImageButton but I dont know how to fix it. Below there is the XAML code. Hopefully somebody can help. Thanks!
<StackLayout>
<Label Text="Discover" TextColor="Black" FontSize="24" FontAttributes="Bold" Margin="15" />
<CarouselView ItemsSource="{Binding plants}" HeightRequest="300" PeekAreaInsets="100">
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame HeightRequest="280" WidthRequest="180" BackgroundColor="Wheat" HasShadow="True" Margin="10" Padding="0" HorizontalOptions="CenterAndExpand" CornerRadius="10" >
<Grid>
<StackLayout>
<ImageButton Source="{Binding imgsource}" VerticalOptions="FillAndExpand"
Aspect="AspectFill" Opacity="0.8" Clicked="ImageButton_Clicked"/>
</StackLayout>
<StackLayout Margin="0,10" >
<Image Source="https://icons-for-free.com/iconfiles/png/512/bookmark-131964752402712733.png" HeightRequest="35"
Aspect="AspectFit" HorizontalOptions="EndAndExpand" Margin="5,-15"/>
<Label Text="{Binding name_norm}" TextColor="Black" FontSize="16" FontAttributes="Bold"
Margin="15,-10,0,0" VerticalOptions="EndAndExpand" />
<StackLayout Orientation="Horizontal" Margin="15,-8,0,0" >
<Image Source="https://www.freeiconspng.com/thumbs/info-icon/info-icon-24.png" HeightRequest="15"
Aspect="AspectFit"/>
<Label Text="{Binding name_lat}" TextColor="Black" FontSize="16" FontAttributes="Italic" VerticalOptions="EndAndExpand" Margin="-5,0" />
</StackLayout>
</StackLayout>
</Grid>
</Frame>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<Label x:Name="label" Text="0 ImageButton clicks"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
</StackLayout>
Here the C# Code:
namespace PlantBase
{
public partial class MainPage : ContentPage
{
int clickTotal;
public MainPage()
{
InitializeComponent();
}
private void ImageButton_Clicked(object sender, EventArgs e)
{
clickTotal += 1;
label.Text = $"{clickTotal} ImageButton click{(clickTotal == 1 ? "" : "s")}";
}
}
}
Check VisualElement.InputTransparent Property.
false if the element and its children should receive input; true if neither the element nor its children should receive input and should, instead, pass inputs to the elements that are visually behind the current visual element. Default is false.
What you need is to set InputTransparent to true on the text stackLayout .
<StackLayout InputTransparent="True" Margin="0,10" VerticalOptions="EndAndExpand" BackgroundColor="SaddleBrown">
<Label Text="{Binding name_norm}" TextColor="White" FontSize="16" FontAttributes="Bold" Margin="15,-10,0,0" VerticalOptions="EndAndExpand" />
<StackLayout Orientation="Horizontal" Margin="15,-8,0,0" BackgroundColor="Aqua">
<Image Source="https://www.freeiconspng.com/thumbs/info-icon/info-icon-24.png" HeightRequest="15" Aspect="AspectFit" />
<Label Text="{Binding name_lat}" TextColor="White" FontSize="16" FontAttributes="Italic" VerticalOptions="EndAndExpand" Margin="-5,0" />
</StackLayout>
</StackLayout>
Okay I found the Problem. It was that before I put the red Flag on the Top and the text at the bottom in one Stacklayout which expanded from top to bottom. Now that i put them in seperate StackLayouts it works and the ImageButton is free.
Pictures before/after.
old StackLayout
new Stacklayout
The new XAML is:
<CarouselView ItemsSource="{Binding plants}" HeightRequest="300" PeekAreaInsets="100">
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame HeightRequest="280" WidthRequest="180" BackgroundColor="Wheat" HasShadow="True" Margin="10" Padding="0" HorizontalOptions="CenterAndExpand" CornerRadius="10" >
<Grid>
<StackLayout>
<ImageButton Source="{Binding imgsource}" VerticalOptions="FillAndExpand"
Aspect="AspectFill" Opacity="0.9" Clicked="ImageButton_Clicked" />
</StackLayout>
<StackLayout VerticalOptions="StartAndExpand" HorizontalOptions="EndAndExpand" BackgroundColor="Aqua">
<ImageButton Source="https://icons-for-free.com/iconfiles/png/512/bookmark-131964752402712733.png" HeightRequest="35"
Aspect="AspectFit" HorizontalOptions="EndAndExpand" Margin="5,0" BackgroundColor="Transparent" Clicked="ImageButton_Clicked_1" />
</StackLayout>
<StackLayout Margin="0,10" VerticalOptions="EndAndExpand" BackgroundColor="SaddleBrown">
<Label Text="{Binding name_norm}" TextColor="White" FontSize="16" FontAttributes="Bold"
Margin="15,-10,0,0" VerticalOptions="EndAndExpand" />
<StackLayout Orientation="Horizontal" Margin="15,-8,0,0" BackgroundColor="Aqua" >
<Image Source="https://www.freeiconspng.com/thumbs/info-icon/info-icon-24.png" HeightRequest="15"
Aspect="AspectFit" />
<Label Text="{Binding name_lat}" TextColor="White" FontSize="16" FontAttributes="Italic" VerticalOptions="EndAndExpand" Margin="-5,0" />
</StackLayout>
</StackLayout>
</Grid>
</Frame>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
New Question now. Since at the bottom there is the Text StackLayout, where the Text is I cant press the ImageButton. How can I put the ImageButton as top "layer" so I can also press it while pressing on the text.

Auto-stack labels in stacklayout without margin

I'm having problem with not being able to stack two labels in a StackLayout and fit the content without a margin.
Expected result:
Current output:
I have tried and set the VerticalOptions, Margin and Padding properties but it still contains the margin (the red background) as well as the second content is not touching the "ceiling" of it's StackLayout parent.
Current code:
<ViewCell>
<StackLayout Orientation="Horizontal" VerticalOptions="Start">
<StackLayout HorizontalOptions="Center" VerticalOptions="Center">
<Image Source="summary.png"/>
</StackLayout>
<StackLayout Orientation="Vertical" VerticalOptions="Start" BackgroundColor="Red" Margin="0" Padding="0">
<StackLayout BindingContext="{Binding Date}" VerticalOptions="Start" BackgroundColor="Beige" Margin="0" Padding="0">
<Label Text="{Binding Text}" TextColor="{Binding Color}" VerticalOptions="Start"/>
</StackLayout>
<StackLayout BindingContext="{Binding Result}" VerticalOptions="Start" BackgroundColor="Blue" Margin="0" Padding="0">
<Label Text="{Binding Text}" TextColor="{Binding Color}" FontSize="{Binding FontSize}" VerticalOptions="Start"/>
</StackLayout>
</StackLayout>
</StackLayout>
</ViewCell>

Add a border to the web view

I'm working on a Xamarin Forms project using Visual studio 2017 , I want to add a border to the web view . with black color . how to do that view xaml is below .
<StackLayout Orientation="Vertical" BackgroundColor="White" HorizontalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal" HeightRequest="60" HorizontalOptions="FillAndExpand" BackgroundColor="DarkBlue" Padding="5">
<Label x:Name="lblUserNewOnBoarding" WidthRequest="340" Text="New User Onboarding" FontAttributes="Bold" FontFamily="Roboto" FontSize="Large" TextColor="White"
HorizontalOptions="StartAndExpand" VerticalOptions="CenterAndExpand"></Label>
<Button x:Name="bntCancel" Text="Cancel" HeightRequest="40" BackgroundColor="#4184f3"
TextColor="White" HorizontalOptions="EndAndExpand" VerticalOptions="CenterAndExpand" Clicked="HandleCancle_Clicked" FontFamily="Roboto" FontSize="Small" FontAttributes="Bold">
<Button.Image>
<FileImageSource File="baseline_cancel_white_18dp.png" ></FileImageSource>
</Button.Image>
</Button>
</StackLayout>
<StackLayout Orientation="Vertical" HorizontalOptions="CenterAndExpand" >
<Label Text="Please agree to the following terms and conditions…" FontFamily="Roboto-Medium" FontSize="30"
HorizontalOptions="CenterAndExpand" WidthRequest="927" HeightRequest="168" Margin="5"
TextColor="Black"></Label>
<WebView x:Name="wvAgree" HeightRequest="300" WidthRequest="400" Margin="50" BackgroundColor="White" ></WebView>
<Button x:Name="btnAgree" Text="Agree" WidthRequest="190" HeightRequest="50" AnchorX="417" AnchorY="604"
BackgroundColor="#4184f3" TextColor="White" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" Clicked="HandleAgree_Clicked" FontFamily="Roboto" FontSize="Small" FontAttributes="Bold">
<Button.Image >
<FileImageSource File="Agree.png"></FileImageSource>
</Button.Image>
</Button>
<Button x:Name="btnDisAgree" Text="Disagree" WidthRequest="190" HeightRequest="50" AnchorX="417" AnchorY="673" BackgroundColor="#4184f3"
TextColor="White" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" Clicked="HandleDisAgree_Clicked" FontFamily="Roboto" FontSize="Small" FontAttributes="Bold">
<Button.Image>
<FileImageSource File="baseline_delete_48.png" ></FileImageSource>
</Button.Image>
</Button>
</StackLayout>
</StackLayout>
Wrap your WebView around Frame. So:
<Frame OutlineColor="Black">
<WebView x:Name="wvAgree" HeightRequest="300" WidthRequest="400" Margin="50" BackgroundColor="White"/>
</Frame>
Also you dont have to write a Additional closing Tag if you dont put anything between it. Pay attention how I closed that WebView tag.

I am using a label as a button. How can I surround it with a border with round edges?

Here is the code that I am using with Xamarin Forms:
<Grid Grid.Column="0" ColumnSpacing="0" Margin="0,0,10,0">
<Label Grid.Column="0" x:Name="faveIconLabel" Style="{StaticResource mediumIcon}" Margin="0,2,0,0" HorizontalOptions="Fill" FontFamily="FontAwesome" VerticalOptions="Center" VerticalTextAlignment="Center" />
<Label Grid.Column="1" x:Name="hiddenIconLabel" Style="{StaticResource mediumIcon}" Margin="0,2,0,0" HorizontalOptions="Fill" FontFamily="FontAwesome" VerticalOptions="Center" VerticalTextAlignment="Center" />
</Grid>
Can someone help and let me know how I can surround these two labels with a border to make them as much as possible look like buttons.
Frame can be used for this very purpose:
<Grid Grid.Column="0" ColumnSpacing="0" Margin="0,0,10,0">
<Frame Grid.Column="0" CornerRadius="5" OutlineColor="Black">
<Label x:Name="faveIconLabel" Style="{StaticResource mediumIcon}" Margin="0,2,0,0" HorizontalOptions="Fill" FontFamily="FontAwesome" VerticalOptions="Center" VerticalTextAlignment="Center" />
</Frame>
<Frame Grid.Column="1" CornerRadius="5" OutlineColor="Black">
<Label x:Name="hiddenIconLabel" Style="{StaticResource mediumIcon}" Margin="0,2,0,0" HorizontalOptions="Fill" FontFamily="FontAwesome" VerticalOptions="Center" VerticalTextAlignment="Center" />
</Frame>
</Grid>

Resources