How to increase size of a Grid that Contains a Drawing Canvas in a Stack Layout in Xamarin - xaml

My code below creates what is shown in the picture below where the label's text is from an API I am calling. Also the drawing canvas is taken from https://github.com/xamarin/xamarin-forms-samples/tree/master/SkiaSharpForms/Demos/Demos/SkiaSharpFormsDemos. I was wondering how to make the drawing canvas more larger in height? Thank you.
<?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:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
xmlns:tt="clr-namespace:TouchTracking"
x:Class="MathKumu.Pages.WorkPage">
<ContentPage.Content>
<StackLayout>
<Label Text="{Binding EquationString}" />
<Entry Placeholder="Put Answer Here" />
<Grid BackgroundColor="White">
<skia:SKCanvasView x:Name="canvasView"
PaintSurface="OnCanvasViewPaintSurface"/>
<Grid.Effects>
<tt:TouchEffect Capture="True"
TouchAction="OnTouchEffectAction" />
</Grid.Effects>
</Grid>
</StackLayout>
</ContentPage.Content>
</ContentPage>

Change your StackLayout to a Grid and specify that Row 2 has a Height of *. That will force Row 2 to consume all extra space.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
xmlns:tt="clr-namespace:TouchTracking"
x:Class="MathKumu.Pages.WorkPage">
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<Grid.RowDefinitions>
<Label Grid.Row="0" Text="{Binding EquationString}" />
<Entry Grid.Row="1" Placeholder="Put Answer Here" />
<Grid Grid.Row="2" BackgroundColor="White">
<skia:SKCanvasView x:Name="canvasView"
PaintSurface="OnCanvasViewPaintSurface"/>
<Grid.Effects>
<tt:TouchEffect Capture="True"
TouchAction="OnTouchEffectAction" />
</Grid.Effects>
</Grid>
</Grid>
</ContentPage.Content>
</ContentPage>

Related

Xaml layout, box to the left corner over another box

I am trying to get to this layout.
I got the red part correct but I am not able to position green box on top of the left part of the red box.
Green box needs to have same width as left part of the red part.
Green box has to be on the view from top to bottom.
This is my code so far. I am absolute xaml beginner so I have no clue if its even possible to do this kind of layout.
<?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="HOT_App.Views.ItemsPage"
Title="{Binding Title}"
x:Name="BrowseItemsPage">
<StackLayout>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="80"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"></ColumnDefinition>
</Grid.ColumnDefinitions>
<BoxView BackgroundColor="red" Grid.Row="0"></BoxView>
<BoxView BackgroundColor="red" Grid.Column="1"></BoxView>
<BoxView WidthRequest="300" BackgroundColor="green" Grid.Row="1"></BoxView>
<BoxView BackgroundColor="Aqua" Grid.Row="1" Grid.Column="1"></BoxView>
</Grid>
</StackLayout>
</ContentPage>
use RowSpan to make an element span multiple rows
<BoxView BackgroundColor="green" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" />

Multiple BindingContext's On Same ContentPage, Two different Views?

I have a ContentPage with two ContentViews on it and i want to set the binding context for each of them each to their own respective ViewModel (this is my preferred soultion over one massive ViewModel for them combined)
MainPage
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="MVVMFramework.VVMs.Main.MainPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MVVMFramework"
xmlns:nav="clr-namespace:MVVMFramework.Navigation.NavigationHeader"
xmlns:vm="clr-namespace:MVVMFramework.VVMs.Main">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="200" />
</Grid.RowDefinitions>
//ContentView For Header
<ContentView Grid.Row="0"
HorizontalOptions="Start"
VerticalOptions="Start">
Content="{Binding NavHeader}"
<!--<ContentView.BindingContext>
<nav:NavigationHeaderViewModel />
</ContentView.BindingContext>-->
</ContentView>
//ContentView For Body of the app
<ContentView Grid.Row="1"
Content="{Binding DisplayedView}"
HorizontalOptions="Center"
VerticalOptions="Center">
<!--<ContentView.BindingContext>
<vm:MainPageViewModel />
</ContentView.BindingContext>-->
</ContentView>
</Grid>
</ContentPage>
When I uncomment both bindingcontext attributes the App compiles, and starts to run and then crashes when loading the MainPage.
Am i not implementing this correctly ?, is there another way to do it ?
Answer
You can specify the source for each view's binding using its BindingContext property like so:
BindingContext="{Binding Source = {Your Binding Source}}"
Sample App
Here's a sample app that shows how to reference multiple view models from the same ContentPage: https://github.com/brminnick/MultipleViewModelSample/
Code
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="MVVMFramework.VVMs.Main.MainPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MVVMFramework"
xmlns:nav="clr-namespace:MVVMFramework.Navigation.NavigationHeader"
xmlns:vm="clr-namespace:MVVMFramework.VVMs.Main">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="200" />
</Grid.RowDefinitions>
<ContentView
Grid.Row="0"
Content="{Binding NavHeader}"
HorizontalOptions="Start"
VerticalOptions="Start"
BindingContext="{Binding Source = {nav:NavigationHeaderViewModel}}"/>
<ContentView
Grid.Row="1"
Content="{Binding DisplayedView}"
HorizontalOptions="Center"
VerticalOptions="Center"
BindingContext="{Binding Source = {vm:MainPageViewModel}}"/>
</Grid>
</ContentPage>

Xamarin Forms Label User Control

I'm trying to create a Xamarin Forms user control containing a label and a placeholder where I can "nest" a child control.
I want the label on the left and the nested control on the right. They need to take a percentage of the available space i.e. the label should take one third and the nested control 2 thirds.
I'm trying to use a content presenter as a placeholder so I can use the user control like this
<userControls:PanelControl HeadingText="FIRST HEADING">
<DatePicker />
</userControls:PanelControl>
If I base the user control on a Stack Layout, the two controls appear in the correct position. The issue with using a Stack Layout is I can't implement percentage widths.
If I base the user control on a Grid, the nested control appears in the first column ovewriting the label. It looks like the Content Presenter does not work properly in a Grid.
Here is the Stack Layout based user control
<?xml version="1.0" encoding="UTF-8"?>
<StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="BasicAppTemplate.UserControls.PanelControl"
Orientation="Horizontal">
<Label x:Name="HeadingLabel" VerticalOptions="Center"/>
<ContentPresenter/>
</StackLayout>
Here is the Grid based user control
<?xml version="1.0" encoding="UTF-8"?>
<Grid xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="BasicAppTemplate.UserControls.PanelGridControl">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Label x:Name="HeadingLabel" VerticalOptions="Center" Grid.Column="0"/>
<StackLayout Grid.Column="1">
<ContentPresenter/>
</StackLayout>
</Grid>
Here is the page
<?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:userControls="clr-namespace:BasicAppTemplate.UserControls;assembly=BasicAppTemplate"
x:Class="BasicAppTemplate.Pages.MainPage">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<userControls:PanelControl HeadingText="FIRST HEADING">
<DatePicker />
</userControls:PanelControl>
<userControls:PanelGridControl HeadingText="SECOND HEADING" Grid.Row="1">
<DatePicker />
</userControls:PanelGridControl>
</Grid>
</ContentPage>
This what they both look like
Any ideas how to implement this? Is there another way I can create my nested user control?
Thanks to the pointer from DavidS the solution is to embed a ControlTemplate within the User Control
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="BasicAppTemplate.UserControls.PanelGridControl">
<ContentView.ControlTemplate>
<ControlTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Label VerticalOptions="Center" Grid.Column="0" Text="{TemplateBinding HeadingText}" />
<ContentPresenter Grid.Column="1" />
</Grid>
</ControlTemplate>
</ContentView.ControlTemplate>
</ContentView>

Scrollview scrolls up-and-over other content when scrolling

When layin out this form, I want a header the size of its content, footer the size of the content, and a middle that expands to take up the rest. Easy in XAML/UWP. But in Xamarin Forms when the ScrollView content has data it floats and overlays the top and bottom. Also when I drag/scroll the ScrollView it can go to the top of the screen. How to dock the scrollview properly so I have a scrolling middle region? Thx...
Pictures and XAML layout 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"
x:Class="BaseProject.MainPage">
<Label Text="{Binding MainText}" VerticalOptions="Center" HorizontalOptions="Center" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TableView Grid.Row="0" Intent="Settings" BackgroundColor="Blue" HeightRequest="150" >
<TableSection Title="Search">
<ViewCell>
<Button x:Name="Button_Search" Text="Go"/>
</ViewCell>
<EntryCell x:Name="Entry_Cell_SearchFor" />
</TableSection>
</TableView>
<ScrollView Grid.Row="1" VerticalOptions="FillAndExpand" Orientation="Vertical">
<StackLayout BackgroundColor="Red" >
<Label Text="body" x:Name="Label_Body" BackgroundColor="Yellow" />
</StackLayout>
</ScrollView>
<StackLayout Grid.Row="2">
<Label Text="footer"/>
</StackLayout>
</Grid>
</ContentPage>
Set IsClippedToBounds property as true of ScrollView

Xamarin Forms Center CollectionView content

I have a problem. I created a page that looks like this:
Now I want the content of the CollectionView to be centered. I already tried things to set on HorizontalOptions=Center, but no luck!
Here is the code of that part:
<StackLayout HorizontalOptions="CenterAndExpand">
<CollectionView ItemsSource="{Binding coinDataList}" ItemsLayout="HorizontalList" Margin="0" HorizontalOptions="CenterAndExpand" BackgroundColor="Red">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid RowSpacing="0" Margin="20,0,20,0" HorizontalOptions="CenterAndExpand" Padding="0">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="5" />
<RowDefinition Height="20" />
<RowDefinition Height="10" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Label Grid.Row="0" VerticalOptions="CenterAndExpand" HorizontalOptions="Center" Text="{Binding Coin}" FontAttributes="Bold" TextColor="#00D8FF" FontSize="18"/>
<Label Grid.Row="2" VerticalOptions="CenterAndExpand" HorizontalOptions="Center" Text="{Binding Price, StringFormat='{0:F2}'}" TextColor="White" FontSize="18"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
How can I do that?
You can achieve this by using BindableLayout in conjunction with the StackLayout with horizontal orientation. This will not be as performant as CollectionView, but from your UI, it looks like you will not be having a lot of items in your ItemSource collection, but you your need UI to be dynamic and evenly spaced and centered when there are fewer items. As the item list grows, the UI will look more like the horizontal list view.
So here is the minimal working XAML which you can modify to fit into your project. For sake of simplicity, I have added everything in the XAML (no code behind), so you can plug this XAML right into the content page and test it out!
<?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:generic="clr-namespace:System.Collections.Generic;assembly=netstandard"
mc:Ignorable="d"
x:Class="Playground.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<generic:List x:Key="SymbolNames" x:TypeArguments="x:String">
<x:String>BTC</x:String>
<x:String>LTC</x:String>
<x:String>ETH</x:String>
<x:String>OT1</x:String>
<x:String>OT2</x:String>
<x:String>OT3</x:String>
<x:String>OT4</x:String>
<x:String>OT5</x:String>
<x:String>OT6</x:String>
</generic:List>
</ResourceDictionary>
</ContentPage.Resources>
<ScrollView Orientation="Horizontal" HeightRequest="60" VerticalOptions="Start">
<StackLayout BindableLayout.ItemsSource="{Binding Source={StaticResource SymbolNames}}" Orientation="Horizontal">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Label Text="{Binding}" HorizontalOptions="CenterAndExpand" VerticalOptions="Center" Margin="10"/>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ScrollView>
</ContentPage>
UI when 3 Items:
UI When multiple overflowing items: