I am quite new to this, but I am trying to figure out how to dynamically add entries with a button click.
I am creating new entries with each button click but my issue is that the entries are placed under the button instead of ontop of it.
Here is how my app looks like:
[![enter image description here][1]][1]
By clicking the `Add Ingredient` button, I want to add a new entry.
This is what the front end looks like:
<?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="EasyChef.Views.AboutPage"
xmlns:vm="clr-namespace:EasyChef.ViewModels"
Title="{Binding Title}">
<ContentPage.BindingContext>
<vm:AboutViewModel />
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<Color x:Key="Accent">#96d1ff</Color>
</ResourceDictionary>
</ContentPage.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackLayout BackgroundColor="{StaticResource Accent}" VerticalOptions="FillAndExpand" HorizontalOptions="Fill">
<StackLayout Orientation="Horizontal" HorizontalOptions="Center" VerticalOptions="Center">
<ContentView Padding="0,40,0,40" VerticalOptions="FillAndExpand">
<Label Text="EasyChef" TextColor="Black" FontSize="24" FontAttributes="Bold" Margin="10"/>
</ContentView>
</StackLayout>
</StackLayout>
<ScrollView Grid.Row="1">
<StackLayout Orientation="Vertical" Padding="30,24,30,24" Spacing="10">
<Label Text="Simply select ingredients!" FontSize="Title"/>
<StackLayout x:Name="EntriesStackLayout">
<Grid VerticalOptions="CenterAndExpand" Margin="20" RowSpacing="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Entry Placeholder="Eg. Eggs" x:Name="EntryTag" Grid.Row="0"/>
<Button Text="Add Ingredient" Grid.Row="1" Clicked="Button_Clicked"/>
</Grid>
</StackLayout>
<CheckBox />
</StackLayout>
</ScrollView>
</Grid>
</ContentPage>
And the back end()
public partial class AboutPage : ContentPage
{
int x = 1;
public AboutPage()
{
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
AddEntry(EntriesStackLayout, "Ingredient " + x.ToString());
x++;
}
private void AddEntry(StackLayout sl, string name)
{
Entry entry = new Entry()
{
Placeholder = name,
};
sl.Children.Add(entry);
}
}
My preferred solution would be to create new entries with each button click, but I am happy with having default entries and unhiding them in order with a click.
A simple method is to move the Button to the outside of the StackLayout(StackLayout x:Name="EntriesStackLayout") and below the StackLayout.
Please refer to the following code:
<ScrollView Grid.Row="1">
<StackLayout Orientation="Vertical" Padding="30,24,30,24" Spacing="10">
<Label Text="Simply select ingredients!" FontSize="Title"/>
<StackLayout x:Name="EntriesStackLayout">
<Grid VerticalOptions="CenterAndExpand" Margin="20" RowSpacing="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Entry Placeholder="Eg. Eggs" x:Name="EntryTag" Grid.Row="0"/>
<!--<Button Text="Add Ingredient" Grid.Row="1" Clicked="Button_Clicked"/>-->
</Grid>
</StackLayout>
<!--move button here-->
<Button Text="Add Ingredient" Grid.Row="1" Clicked="Button_Clicked"/>
<CheckBox />
</StackLayout>
</ScrollView>
Related
I have a pretty straight forward question.
With this code, I create new entries whenever i click a button:
XAML
<Button Text="Add Ingredient" Grid.Row="1" Clicked="Button_Clicked"/>
Code-behind
private void Button_Clicked(object sender, EventArgs e)
{
AddEntry(EntriesStackLayout, "Ingredient " + x.ToString());
x++;
}
private void AddEntry(StackLayout sl, string name)
{
Entry entry = new Entry()
{
Placeholder = name,
};
sl.Children.Add(entry);
}
I want to know what could I do to then remove these entries in order. For last to first?
This is what the app looks like:
I want to know what could I do to then remove these entries in order.
For last to first?
For your problem, you can remove the last element one by one in your StackLayout(EntriesStackLayout).
Please refer to the following code:
private void Button_Clicked_Remove(object sender, EventArgs e)
{
var element = EntriesStackLayout.Children.LastOrDefault();
if (element!=null) {
EntriesStackLayout.Children.Remove(element);
}
}
YouPage.xaml
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="Fill">
<StackLayout Orientation="Horizontal" HorizontalOptions="Center" VerticalOptions="Center">
<ContentView Padding="0,40,0,40" VerticalOptions="FillAndExpand">
<Label Text="EasyChef" TextColor="Black" FontSize="24" FontAttributes="Bold" Margin="10"/>
</ContentView>
</StackLayout>
</StackLayout>
<ScrollView Grid.Row="1">
<StackLayout Orientation="Vertical" Padding="30,24,30,24" Spacing="10">
<Label Text="Simply select ingredients!" FontSize="Title"/>
<StackLayout x:Name="EntriesStackLayout">
<Grid VerticalOptions="CenterAndExpand" Margin="20" RowSpacing="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Entry Placeholder="Eg. Eggs" x:Name="EntryTag" Grid.Row="0"/>
</Grid>
</StackLayout>
<Button Text="Add Ingredient" Grid.Row="1" Clicked="Button_Clicked"/>
<Button Text="Relete Ingredient" Grid.Row="1" Clicked="Button_Clicked_Remove"/>
<CheckBox />
</StackLayout>
</ScrollView>
</Grid>
Note:
Make sure to add a null judgement, or the app may crash:
if (element!=null) {
EntriesStackLayout.Children.Remove(element);
}
To remove an element from a layout
sl.Children.Remove(element);
If you don’t already have a reference to the element
var element = sl.Children.LastOrDefault();
I have several generic buttons. Both title and the corresponding icon are displayed correctly, but the tap function does not work.
HomePage.xaml with the ScanningApp control
<?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="primetals.ScannerApp.Views.HomePage"
xmlns:controls="clr-namespace:primetals.ScannerApp.Controls"
xmlns:resource="clr-namespace:primetals.ScannerApp"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
BackgroundColor="White"
x:Name="self"
Title="{Binding Title}">
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="controls:ScanningApp">
<Setter Property="WidthRequest" Value="220"></Setter>
<Setter Property="HeightRequest" Value="220"></Setter>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="3*"></RowDefinition>
<RowDefinition Height="3*"></RowDefinition>
<RowDefinition x:Name="backgroundImageRow" Height="4*"></RowDefinition>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" HorizontalOptions="CenterAndExpand" Margin="0,10,0,10">
<!-- Application Logo -->
<Image Source="icon_scannerapp.png" WidthRequest="96" HeightRequest="96"></Image>
<!-- Welcome Text -->
<Label Text="{x:Static resource:ApplicationResources.WelcomeMessageLine1}" FontSize="Large">
</Label>
<Label FontSize="Large">
<Label.FormattedText>
<FormattedString>
<Span Text="{x:Static resource:ApplicationResources.WelcomeMessageLine2}"></Span>
<Span Text="{x:Static resource:ApplicationResources.WelcomeMessageSpareParts}" FontAttributes="Bold" FontSize="Large"></Span>
<Span Text="{x:Static resource:ApplicationResources.WelcomeMessageOr}"></Span>
<Span Text="{x:Static resource:ApplicationResources.WelcomeMessageSensorData}" FontAttributes="Bold" FontSize="Large"></Span>
<Span Text="!"></Span>
</FormattedString>
</Label.FormattedText>
</Label>
</StackLayout>
<!-- Scanning Applications -->
<StackLayout Orientation="Horizontal" Grid.Row="1" BindableLayout.ItemsSource="{Binding Apps}" HorizontalOptions="Center" VerticalOptions="Start">
<BindableLayout.ItemTemplate>
<DataTemplate>
<controls:ScanningApp Margin="0,0,5,0"
ImageSource="{Binding ImageUrl}"
TapImageSource="{Binding TapImageUrl}"
Text="{Binding Title}"
TappedCommand="{Binding BindingContext.AppTappedCommand, Source={x:Reference self}}"
TappedCommandParameter="{Binding}">
</controls:ScanningApp>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
<!-- Background Image -->
<Image x:Name="backgroundImage" Grid.Row="2" Source="background_scannerapp_PT.jpg" Aspect="AspectFit" HorizontalOptions="Fill" VerticalOptions="Fill"></Image>
</Grid>
</ContentPage>
HomepageViewModel.cs:
AppTappedCommand is set correctly
this.AppTappedCommand = new DelegateCommand<ScanApplication>((app) => OnGotoScanPage(app));
this.Title = ApplicationResources.ApplicationTitleCaption;
public async void OnGotoScanPage(ScanApplication app)
{
NavigationParameters parameters = new NavigationParameters();
parameters.Add(Constants.Parameters.App, app.AppId);
await this.NavigationService.NavigateAsync($"{nameof(ScanPage)}", parameters);
}
ScanningApp.xaml.cs:
After Clicking the button TappedCommand is null.
public static readonly BindableProperty TappedCommandProperty = BindableProperty.Create(nameof(TappedCommand), typeof(ICommand), typeof(ScanningApp), default(ICommand), Xamarin.Forms.BindingMode.OneWay);
public ICommand TappedCommand
{
get
{
return (ICommand)GetValue(TappedCommandProperty);
}
set
{
SetValue(TappedCommandProperty, value);
}
}
public static readonly BindableProperty TappedCommandParameterProperty = BindableProperty.Create(nameof(TappedCommandParameter), typeof(object), typeof(ScanningApp), null, Xamarin.Forms.BindingMode.OneWay);
public object TappedCommandParameter
{
get
{
return GetValue(TappedCommandParameterProperty);
}
set
{
SetValue(TappedCommandParameterProperty, value);
}
}
private bool OnExecuteTap()
{
img.Source = this.ImageSource;
if (this.TappedCommand != null && this.TappedCommand.CanExecute(this.TappedCommandParameter))
{
this.TappedCommand.Execute(this.TappedCommandParameter);
}
return false;
}
ScanningApp.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="primetals.ScannerApp.Controls.ScanningApp"
x:Name="self">
<Grid Padding="1" BackgroundColor="{StaticResource PrimetalsLightGrayColor}">
<Grid>
<Grid.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"></TapGestureRecognizer>
</Grid.GestureRecognizers>
<Grid.RowDefinitions>
<RowDefinition Height="5*"></RowDefinition>
<RowDefinition Height="1*" ></RowDefinition>
</Grid.RowDefinitions>
<Image x:Name="img" Grid.Row="0" Source="{Binding ImageSource, Source={x:Reference self}}" Aspect="AspectFit" VerticalOptions="CenterAndExpand"
Margin="20"></Image>
<Label Grid.Row="1" Text="{Binding Text, Source={x:Reference self}}"
Margin="10,0,10,10"
FontSize="Medium" TextColor="{StaticResource PrimetalsAccentColor}"
VerticalTextAlignment="Center" HorizontalTextAlignment="Center"></Label>
</Grid>
</Grid>
</ContentView>
Originally this sourcecode worked (about one year ago) (but there may be problems with new packages in VS). I hope you can help me. Thanks a lot!
br
It seems that there should be a TapGestureRecognizer_Tapped event handler in ScanningApp.xaml.cs from your code.
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"></TapGestureRecognizer>
So you could do like :
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
img.Source = this.ImageSource;
if (this.TappedCommand != null && this.TappedCommand.CanExecute(this.TappedCommandParameter))
{
this.TappedCommand.Execute(this.TappedCommandParameter);
}
}
Good morning!
I've a big problem with ListViews in Xamarin Forms: my items aren't shown.
This is my xml code:
<?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"
mc:Ignorable="d"
x:Class="KOTC.Views.News">
<ContentPage.Content>
<StackLayout>
<ListView x:Name="list" HasUnevenRows="true" IsVisible="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Text ="{Binding title}" Grid.Row="0" VerticalOptions="CenterAndExpand" FontSize="10" TextColor="Black"/>
<Label Text="{Binding date}" Grid.Row="1" FontSize="10"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
and this is my class constructor:
public News()
{
InitializeComponent();
ObservableCollection<ListNewsItem> listNews = new ObservableCollection<ListNewsItem>();
RemoteDBConnection conn = new RemoteDBConnection(QUERY);
conn.Connect();
List<Models.News> news = conn.ExecuteQueryWithResponse(QUERY);
for (int i = 0; i < news.Count; i++)
{
ListNewsItem item = new ListNewsItem
{
date = news[i].publicationDate,
title = news[i].title
};
listNews.Add(item);
}
list.ItemsSource = listNews;
}
In this moment method ExecuteQueryWithResponse() returns 3 items, that are detected by ListView, in fact when I start the app, I see 3 ViewCells. The problem is that these viewcells are empty, they're not showing data.
Someone can help me?
I am currently trying to build two separate collection views on the same page in Xamarin. I keep getting the error that content is set more than once and also that I've set the content binding more than once. How do I add different bindings to two separate collection views on the same page?
ConsumerOrders.xaml 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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:viewmodels="clr-namespace:Shared.ViewModel"
mc:Ignorable="d"
x:Class="Shared.consumerOrders">
<ContentPage.BindingContext>
<viewmodels:AddedServicesViewModel />
</ContentPage.BindingContext>
<d:ContentPage.BindingContext>
<viewmodels:PastOrderViewModel />
</d:ContentPage.BindingContext>
<ScrollView>
<CollectionView ItemsSource="{Binding ViewAddedServices}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="4"/>
<!--0-->
<RowDefinition Height="30"/>
<!--1-->
<RowDefinition Height="20"/>
<!--2-->
<RowDefinition Height=".25"/>
<!--3-->
<RowDefinition Height="4"/>
<!--4-->
<RowDefinition Height="Auto"/>
<!--5-->
<RowDefinition Height="Auto"/>
<!--6-->
<RowDefinition Height=".25"/>
<!--7-->
<RowDefinition Height="Auto"/>
<!--8-->
<RowDefinition Height="Auto"/>
<!--9-->
<RowDefinition Height=".25"/>
<!--10-->
<RowDefinition Height="Auto"/>
<!--11-->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="4"/>
</Grid.ColumnDefinitions>
<Label Text="Services added" FontAttributes="Bold" TextColor="#F65506" Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" VerticalTextAlignment="End" HorizontalTextAlignment="Start" FontSize="18"/>
<Label Grid.Column="1" Grid.Row="7" BackgroundColor="#707070" Grid.ColumnSpan="3"/>
<!--This is a line-->
<BoxView BackgroundColor="#F0F0F0" Grid.Row="9" Grid.Column="1" Grid.ColumnSpan="3" CornerRadius="22"/>
<Label Grid.Column="1" Grid.Row="9" Padding="10" TextColor="Black" FontSize="18" Text="{Binding BusinessName}" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" Grid.ColumnSpan="2"/>
<Label Grid.Column="3" Grid.Row="9" Padding="0,0,20,0" TextColor="#F65506" FontAttributes="Bold" FontSize="18" Text="View" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand" Grid.ColumnSpan="2"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<CollectionView ItemsSource="{Binding ViewQuoteStatus}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="4"/>
<!--0-->
<RowDefinition Height="30"/>
<!--1-->
<RowDefinition Height="20"/>
<!--2-->
<RowDefinition Height=".25"/>
<!--3-->
<RowDefinition Height="4"/>
<!--4-->
<RowDefinition Height="Auto"/>
<!--5-->
<RowDefinition Height="Auto"/>
<!--6-->
<RowDefinition Height=".25"/>
<!--7-->
<RowDefinition Height="Auto"/>
<!--8-->
<RowDefinition Height="Auto"/>
<!--9-->
<RowDefinition Height=".25"/>
<!--10-->
<RowDefinition Height="Auto"/>
<!--11-->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="4"/>
</Grid.ColumnDefinitions>
<Label Text="Past Orderrs" FontAttributes="Bold" TextColor="#F65506" Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" VerticalTextAlignment="End" HorizontalTextAlignment="Start" FontSize="18"/>
<Label Grid.Column="1" Grid.Row="7" BackgroundColor="#707070" Grid.ColumnSpan="3"/>
<!--This is a line-->
<BoxView BackgroundColor="#F0F0F0" Grid.Row="9" Grid.Column="1" Grid.ColumnSpan="3" CornerRadius="22"/>
<Label Grid.Column="1" Grid.Row="9" Padding="10" TextColor="Black" FontSize="18" Text="{Binding BusinessName}" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" Grid.ColumnSpan="2"/>
<Label Grid.Column="3" Grid.Row="9" Padding="0,0,20,0" TextColor="#F65506" FontAttributes="Bold" FontSize="18" Text="View" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand" Grid.ColumnSpan="2"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ScrollView>
</ContentPage>
AddedServicesViewModel.cs :
using Shared.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
namespace Shared.ViewModel
{
class AddedServicesViewModel
{
readonly IList<AddedServiceStatus> source;
public ObservableCollection<AddedServiceStatus> ViewAddedServices { get; private set; }
public AddedServicesViewModel()
{
source = new List<AddedServiceStatus>();
CreateAddedServicesCollection();
}
void CreateAddedServicesCollection()
{
source.Add(new AddedServiceStatus
{
BusinessName = "Duck's Duct Cleaning"
});
source.Add(new AddedServiceStatus
{
BusinessName = "Rodney's Home Repair"
});
ViewAddedServices = new ObservableCollection<AddedServiceStatus>(source);
}
}
}
PastOrderViewModel :
using Shared.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
namespace Shared.ViewModel
{
class PastOrderViewModel
{
readonly IList<PastOrderStatus> source;
public ObservableCollection<PastOrderStatus> ViewPastOrders { get; private set; }
public PastOrderViewModel()
{
source = new List<PastOrderStatus>();
CreatePastOrderCollection();
}
void CreatePastOrderCollection()
{
source.Add(new PastOrderStatus
{
BusinessName = "Karen's Magnificent Dog Grooming"
});
source.Add(new PastOrderStatus
{
BusinessName = "Harry's In Home Haircuts"
});
source.Add(new PastOrderStatus
{
BusinessName = "Shelly's Floral Arrangements"
});
ViewPastOrders = new ObservableCollection<PastOrderStatus>(source);
}
}
}
You could also bind a ViewModel to each CollectionView separately.
like:
<CollectionView ItemsSource="{Binding ViewAddedServices}">
<CollectionView.BindingContext>
<viewmodels:AddedServicesViewModel/>
</CollectionView.BindingContext>
...
</CollectionView>
<CollectionView ItemsSource="{Binding ViewPastOrders}">
<CollectionView.BindingContext>
<viewmodels:PastOrderViewModel/>
</CollectionView.BindingContext>
...
</CollectionView>
You can't have two ViewModels binding to a SingleView. (as far a I know)
I see that the DataTemplate in both Collections are the same..... there are many ways to refactor....
You could create two CustomView one with the AddedServicesViewModel and the other with PastOrderViewModel
You can merge the two ViewModels into one, and create a CustomView that it's the collection.
Another thing that I see that It could not work is that you can't have a more than one View Nested in a ScrollView
<ScrollView>
<StackLayout> /* Or any other Layout, Grid, Absolute, Flex etc... */
</StackLayout>
</ScrollView>
Another thing is that a CollectionView with orientation vertical in a ScrollView maybe it won't behave as you expect, since the CollectionView with orientation vertical it has Scroll
Two CollectionViews with orientation vertical in the same View it should have a Height, I would do something like this
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<CollectionView Grid.Row="0" ItemsSource="{Binding ViewQuoteStatus}"> ... </CollectionView>
<CollectionView Grid.Row="1" ItemsSource="{Binding ViewAddedServices}"> ... </CollectionView>
</Grid>
or if you create a custom view (custom control)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<MyCustomCollectionView Grid.Row="0" ItemsSource="{Binding ViewQuoteStatus}"> ... </MyCustomCollectionView>
<MyCustomCollectionView Grid.Row="1" ItemsSource="{Binding ViewAddedServices}"> ... </MyCustomCollectionView>
</Grid>
I'm looking for the best way to change the content of a page, without navigating to a new one.
I tried having two stacklayouts, and on a button press I'd change the IsVisible and IsEnabled properties of each stack layout. Although this worked, I was left with a small white gap at the end of each layout (I believe this is a Xamarin.Forms bug).
What would be the best way to accomplish this task? Is there anything built into Xamarin.Forms that can do this that I have missed?
Here is a little sketch design for you to see what I mean:
Before suggesting I use tabs, I'll add that I already have tabs in the application, the sketch doesn't show that though. I need this navigation to work on only ONE page.
The code I used before, that didn't work is:
(Before anybody mentions the poor naming conventions and lack of content, I had to strip it all out as it's code written for an employer.
C#:
private void Button1_Clicked(object sender, EventArgs e)
{
Content2.IsVisible = false;
Content2.IsEnabled = false;
Content1.IsVisible = true;
Content1.IsEnabled = true;
}
private void Button2_Clicked(object sender, EventArgs e)
{
Content2.IsVisible = true;
Content2.IsEnabled = true;
Content1.IsEnabled = false;
Content1.IsVisible = false;
}
XML:
<ScrollView x:Name="content1" VerticalOptions="FillAndExpand" BackgroundColor="#f2f2f2">
<StackLayout Spacing="0">
<StackLayout Orientation="Horizontal" BackgroundColor="White" Padding="20,20,20,20" HorizontalOptions="FillAndExpand">
<StackLayout>
<Label Text="text:" FontFamily="{StaticResource BoldFont}"/>
<StackLayout Orientation="Horizontal">
<Image x:Name="content1image" HeightRequest="25" WidthRequest="25"/>
<Label x:Name="content1label" FontFamily="{StaticResource Font}" FontSize="27" TextColor="#969696"/>
</StackLayout>
</StackLayout>
<StackLayout HorizontalOptions="FillAndExpand">
<Entry x:Name="content1Entry" Keyboard="Numeric" Margin="0,25,0,0" Placeholder="0.00000000" FontFamily="{StaticResource Font}" FontSize="27" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="End" TextColor="#969696"/>
<Label x:Name="content1Label2" FontSize="14" FontFamily="{StaticResource Font}" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="End" TextColor="#969696"/>
</StackLayout>
</StackLayout>
<StackLayout Padding="20,30,20,0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Label Text="content1Label3" FontFamily="{StaticResource Font}"/>
<StackLayout Orientation="Horizontal">
<Button x:Name="content1button" Image="image.png" BackgroundColor="Transparent" HorizontalOptions="Start" Margin="0" WidthRequest="25" HeightRequest="25"/>
<Entry x:Name="content1Entry2" FontFamily="{StaticResource Font}" FontSize="12" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="End"/>
</StackLayout>
</StackLayout>
<StackLayout VerticalOptions="EndAndExpand" Padding="0,-1,0,0">
<Label x:Name="content1Label4" FontSize="19" HorizontalOptions="CenterAndExpand" FontFamily="{StaticResource Font}"/>
<Label x:Name="content1Label5" FontSize="12" TextColor="#b6b6b6" HorizontalOptions="CenterAndExpand" FontFamily="{StaticResource Font}"/>
<Button x:Name="content1Button2" VerticalOptions="End" HorizontalOptions="FillAndExpand" BorderRadius="25" BackgroundColor="#2r432d" BorderColor="#2r432d" TextColor="White" FontFamily="{StaticResource Font}" FontSize="20" BorderWidth="3" Margin="10,10,10,10"/>
</StackLayout>
</StackLayout>
I have not had very much success using Stacklayouts. Grids however has a lot of customizability and in my case it expands to fill all the area that you wish for.
This is how I would do it.
Xaml
<Grid x:Name="Grid1" IsVisible="False" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
<Label FontSize="Medium" Text="Grid1 Label"/>
</Grid>
<Grid Grid.Row="1" HeightRequest="100" WidthRequest="375" VerticalOptions="StartAndExpand" HorizontalOptions="CenterAndExpand">
<Button x:Name="btnGrid1"/>
</Grid>
</Grid>
<Grid x:Name="Grid2" IsVisible="False" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
<Label FontSize="Medium" Text="Grid2 Label"/>
</Grid>
<Grid Grid.Row="1" HeightRequest="100" WidthRequest="375" VerticalOptions="StartAndExpand" HorizontalOptions="CenterAndExpand">
<Button x:Name="btnGrid2"/>
</Grid>
</Grid>
Code-behind
private void Button1_Clicked(object sender, EventArgs e)
{
Grid2.IsVisible = false;
Grid1.IsVisible = true;
}
private void Button2_Clicked(object sender, EventArgs e)
{
Grid2.IsVisible = true;
Grid1.IsVisible = false;
}