Xamarin.Forms TapGestureRecognizer not working on IOS - xamarin

I have a very simple Xamarin.Forms app. It's just for testing, and at the moment is just supposed to display messages when different boxes on the screen are tapped. The tap gesture isn't working though.
Here is my XAML:
<!-- Header -->
<Label Text="My Company"
TextColor="White"
FontSize="Large"
BackgroundColor="#a6192e"
HorizontalTextAlignment="Center" />
<!-- Body -->
<FlexLayout FlexLayout.Grow="1">
<!-- Content -->
<BoxView
BackgroundColor="#80225f"
FlexLayout.Grow="1" />
<Grid
BackgroundColor="#80225f"
Padding="20,50,50,20"
RowSpacing="20"
ColumnSpacing="20">
<Grid.RowDefinitions>
<RowDefinition Height="300"/>
<RowDefinition Height="300"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="280"/>
<ColumnDefinition Width="280"/>
<ColumnDefinition Width="280"/>
</Grid.ColumnDefinitions>
<BoxView
x:Name="App1Box"
BackgroundColor="Silver"
Grid.Row="0"
Grid.Column="0"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"/>
<BoxView
BackgroundColor="Gray"
Grid.Row="0"
Grid.Column="0"
HeightRequest="60"
VerticalOptions="Start"/>
<Label
Grid.Row="0"
Grid.Column="0"
HorizontalTextAlignment="Center"
TextColor="White"
FontSize="Large"
FontAttributes="Bold"
Margin="10">
App1</Label>
<BoxView
x:Name="App2Box"
BackgroundColor="Silver"
Grid.Row="0"
Grid.Column="1"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"/>
<BoxView
BackgroundColor="Gray"
Grid.Row="0"
Grid.Column="1"
HeightRequest="60"
VerticalOptions="Start"/>
<Label
Grid.Row="0"
Grid.Column="1"
HorizontalTextAlignment="Center"
TextColor="White"
FontSize="Large"
FontAttributes="Bold"
Margin="10">
App2</Label>
<BoxView
x:Name="App3Box"
BackgroundColor="Silver"
Grid.Row="0"
Grid.Column="2"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"/>
<BoxView
BackgroundColor="Gray"
Grid.Row="0"
Grid.Column="2"
HeightRequest="60"
VerticalOptions="Start"/>
<Label
Grid.Row="0"
Grid.Column="2"
HorizontalTextAlignment="Center"
TextColor="White"
FontSize="Large"
FontAttributes="Bold"
Margin="10">
App3</Label>
<Button Grid.Row="1"
Grid.Column="0"
Text="Test Tap"
Clicked="OnMealsTapped"
WidthRequest="100"
HeightRequest="100"
BackgroundColor="Lime"
TextColor="Red"/>
</Grid>
<!-- Navigation items-->
<BoxView FlexLayout.Basis="50"
FlexLayout.Order="-1"
Color="#80225f" />
<!-- Aside items -->
<BoxView FlexLayout.Basis="50"
Color="#80225f" />
</FlexLayout>
<!-- Footer -->
<Label Text="Test App"
FontSize="Large"
BackgroundColor="Gray"
HorizontalTextAlignment="Center" />
</FlexLayout>
</ContentPage.Content>
And here is my C#:
using System;
using System.Collections.Generic;
using Xamarin.Forms;
namespace TESTAPP
{
public partial class MyPage : ContentPage
{
public MyPage()
{
InitializeComponent();
var App1TapHandler = new TapGestureRecognizer();
var App2TapHandler = new TapGestureRecognizer();
var App3TapHandler = new TapGestureRecognizer();
App1TapHandler.NumberOfTapsRequired = 1;
App1TapHandler.Tapped += OnApp1Tapped;
App2TapHandler.NumberOfTapsRequired = 1;
App2TapHandler.Tapped += OnApp2Tapped;
App3TapHandler.NumberOfTapsRequired = 1;
App3TapHandler.Tapped += OnApp3Tapped;
App1Box.GestureRecognizers.Add(App1BoxTapHandler);
App2Box.GestureRecognizers.Add(App2BoxTapHandler);
App3Box.GestureRecognizers.Add(App3BoxTapHandler);
}
private void OnApp1Tapped(object sender, EventArgs e)
{
DisplayAlert("App1","Lets use App1","OK");
}
private void OnApp2Tapped(object sender, EventArgs e)
{
DisplayAlert("App2", "Lets use App2", "OK");
}
private void OnApp3Tapped(object sender, EventArgs e)
{
DisplayAlert("App3", "Lets use App3", "OK");
}
}
}
Button is there for testing. When tapping button I get the test alert message. Nothing happens when tapping any of the BoxViews.
Why is that not working?

Your problem isn't related to the TapGesture, but you have 2 Boxviews overlapping.
So you will have to add the InputTransparent in the BoxViews that aren't receiving any input:
<BoxView
x:Name="App1Box"
BackgroundColor="Silver"
Grid.Row="0"
Grid.Column="0"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"/>
<BoxView
InputTransparent="true" <!-- Here -->
BackgroundColor="Gray"
Grid.Row="0"
Grid.Column="0"
HeightRequest="60"
VerticalOptions="Start"/>
Repeat for the remaining.

Try to invoke the code in the event handlers on the main thread.
Device.BeginInvokeOnMainThread(() =>
{
//Run the code here.
});

Related

How to filter in Xamarin

I am quite new to Xamarin and I want to make filtering in xamarin. So I have three buttons drinks, food and all. When it is all I want to show all of them and when the drinks button is clicked I only want to show drinks etc.
So here are my buttons:
<StackLayout HorizontalOptions="Center" VerticalOptions="Center">
<Button Text="All" x:Name="All" Clicked="Handle_Filter" TextColor="#EEF2FF" FontSize="18" HorizontalOptions="Center" BackgroundColor="#FF5959" />
</StackLayout>
<StackLayout Grid.Column="1" HorizontalOptions="Center" VerticalOptions="Center">
<Button Text="Food" x:Name="Food" Clicked="Handle_Filter" TextColor="#676FA3" FontSize="18" HorizontalOptions="Center" BackgroundColor="#EEF2FF"/>
</StackLayout>
<StackLayout Grid.Column="2" HorizontalOptions="Center" VerticalOptions="Center">
<Button Text="Drinks" x:Name="Drinks" Clicked="Handle_Filter" TextColor="#676FA3" FontSize="18" HorizontalOptions="Center" BackgroundColor="#EEF2FF"/>
</StackLayout>
And the area which needs to be filtered:
<CollectionView Grid.Row="3" Margin="25" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
SelectionMode="None" ItemsSource="{Binding AllProducts}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" ItemSpacing="20"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<pv:PancakeView HasShadow="True" BackgroundColor="#EEF2FF" VerticalOptions="StartAndExpand"
HorizontalOptions="FillAndExpand">
<Grid ColumnSpacing="3" HorizontalOptions="FillAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<BoxView Grid.RowSpan="1" BackgroundColor="#EEF2FF"/>
<BoxView Grid.Column="1" Grid.RowSpan="1" BackgroundColor="#EEF2FF"/>
<BoxView Grid.Column="2" Grid.RowSpan="1" BackgroundColor="#EEF2FF"/>
<Button
Text="{Binding Name}"
Grid.Column="0"
HorizontalOptions="Center"
VerticalOptions="Center"
TextColor="Black"
BackgroundColor="#EEF2FF"
/>
</Grid>
</pv:PancakeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
And my products:
public class Product
{
public string Type { get; set; }
public string Name { get; set; }
public int Stock { get; set; }
}
And help would be appreciated since I am really new in Xamarin.
Thanks
you can do this with a LINQ query
protected void FilterFood(object sender, EventArgs args)
{
myCollectionView.ItemsSource = AllProducts.Where(x => x.Type == "Food").ToList();
}
Your Buttons in Xaml file:
<StackLayout HorizontalOptions="Center" VerticalOptions="Center">
<Button Text="All" x:Name="All" Clicked="onAllFilterClicked" TextColor="#EEF2FF" FontSize="18" HorizontalOptions="Center" BackgroundColor="#FF5959" />
</StackLayout>
<StackLayout Grid.Column="1" HorizontalOptions="Center" VerticalOptions="Center">
<Button Text="Food" x:Name="Food" Clicked="onFoodFilterClicked" TextColor="#676FA3" FontSize="18" HorizontalOptions="Center" BackgroundColor="#EEF2FF"/>
</StackLayout>
<StackLayout Grid.Column="2" HorizontalOptions="Center" VerticalOptions="Center">
<Button Text="Drinks" x:Name="Drinks" Clicked="onDrinksFilterClicked" TextColor="#676FA3" FontSize="18" HorizontalOptions="Center" BackgroundColor="#EEF2FF"/>
</StackLayout>
Set a name to your CollectionView x:Name="cvProducts"
On your Buttons .cs file:
protected void onAllFilterClicked(object sender, EventArgs args)
{
cvProducts.ItemsSource = AllProducts;
}
protected void onFoodFilterClicked(object sender, EventArgs args)
{
cvProducts.ItemsSource = AllProducts.Select(x => x.Type == "Food").ToList();
}
protected void onDrinksFilterClicked(object sender, EventArgs args)
{
cvProducts.ItemsSource = AllProducts.Select(x => x.Type == "Drinks").ToList();
}

Changing BackgroundColor of Button within Xamarin CollectionView changes the BackgroundColor of every 8th button down. why?

I have a Xamarin CollectionView That uses a Button (Button x:Name="PNameButton") to Change the Background color of the button.
When the Button is clicked the background color changes... However - So does every 8th Button in the CollectionView. Its as if the CollectionView renders new data every 8 or so items, and that new first button gets the changed color property. How do I fix this? Code Follows:
<CollectionView x:Name="PairingsCollectionView" SelectionMode="Multiple" Margin="20,5,20,5" >
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Margin="0" Padding="0,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="35" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<BoxView Grid.Column="0" Grid.Row="0" Margin="0" Color="#333130"/>
<Button x:Name="PNameButton" Margin="0" Padding="0,0,0,0" Grid.Column="0" BackgroundColor="{Binding UseColor}" Text="{Binding PDisplayName}" FontSize="Small" TextColor="Black"
HorizontalOptions="Start" VerticalOptions="Center" Clicked="Button_Clicked" />
<BoxView Grid.Column="1" Grid.Row="0" Color="#333130" Margin="0"></BoxView>
<Label Margin="0" Padding="0,0,0,0" Grid.Column="1" TextColor="White" FontSize="Small"
HorizontalOptions="Center" VerticalOptions="Center" >
<Label.FormattedText>
<FormattedString>
<Span Text="{Binding PDays, StringFormat='{0}Dy'}"/>
<Span Text=" "/>
<Span Text="{Binding PDay}"/>
</FormattedString>
</Label.FormattedText>
</Label>
<BoxView Grid.Row="0" Grid.Column="2" Margin="0" Color="#333130"></BoxView>
<Label Margin="0" Padding="0,0,0,0" Grid.Column="2" Text="{Binding PCredit, StringFormat='{0}'}" TextColor="#F57BFA" FontSize="Small"
HorizontalOptions="Center" VerticalOptions="Center"/>
<BoxView Grid.Row="0" Grid.Column="3" Color="#333130" Margin="0"></BoxView>
<Label Margin="0" Padding="0,0,0,0" Grid.Column="3" Text="{Binding PFlightTime, StringFormat='{0}'}" TextColor="White" FontSize="Small"
HorizontalOptions="Center" VerticalOptions="Center"/>
<BoxView Grid.Row="0" Grid.Column="4" Color="#333130" Margin="0"/>
<Label Margin="0" Padding="0,0,0,0" Grid.Column="4" Text="{Binding PRegionType, StringFormat='{0}'}" TextColor="White" FontSize="Small" HorizontalOptions="Center" VerticalOptions="Center"/>
<BoxView Grid.Row="0" Grid.Column="5" Color="#333130" Margin="0"/>
<CheckBox x:Name="IsSelectedCheckbox" Grid.Row="0" Grid.Column="5" IsChecked="{Binding PIsSelected}" VerticalOptions="Center"/>
<BoxView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="1" Color="LightGray"></BoxView>
<Label Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="1" Text="{Binding PDateModified}" TextColor="Black" FontSize="Small"
HorizontalOptions="Center" VerticalOptions="Center"/>
<BoxView Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="5" Color="LightGray" ></BoxView>
<Label Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="5" Text="{Binding PLayovers}"
TextColor="Coral" FontAttributes="Bold" FontSize="17" HorizontalOptions="Start" VerticalOptions="Center" Margin="5,0,0,0" />
<WebView Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="6" BackgroundColor="#333130"
MinimumHeightRequest="150" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
HeightRequest="{Binding PWebViewHeight}" >
<WebView.Source>
<HtmlWebViewSource Html="{Binding PAllText}"/>
</WebView.Source>
</WebView>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
And in the Code Behind:
private void Button_Clicked(object sender, EventArgs e)
{
try
{
string ChkVal = "";
bool compareBool = false;
bool currentState = false;
Color buttonColer;
string ColorHexVal;
int i = 0;
var thisButton = sender as Button;
buttonColer = thisButton.BackgroundColor;
ColorHexVal = buttonColer.ToHex();
if (buttonColer != Color.FromHex("#F7F75A"))
{
currentState = true;
}
else
{
currentState = false;
}
var PairingItem = ((Button)sender).Parent.BindingContext as Pairings;
compareBool = App.DatabaseNA.GetIsSelected(PairingItem.PID);
if (!compareBool == true)
{
thisButton.BackgroundColor = Color.FromHex("#46AE3C");
}
else
{
thisButton.BackgroundColor = Color.FromHex("#F7F75A");
}
}
catch (Exception ex)
{
DisplayAlert("Alert", ex.InnerException.ToString(), "OK"); //await
}
}
Again - Thank You!!!
The code works great and sets the Background color of the button... The problem is - It sets the Background Color of every Button about 8 items down.
Thanks

ActivityProvider does not run

While the application is calling a web service, I want to show an activity indicator.
So I created the service, the method which is calling the service and the view.
I tested everything with the an android emulator without any troubles, but if I want to debug it on a phone (LG G6), the activity indicator is not spinning..
The control is visible, but the animation is not working...
This is the code:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Button
Grid.Row="0"
Clicked="Button_OnClicked"
HorizontalOptions="Center"
Text="Press"
VerticalOptions="Center" />
<StackLayout
x:Name="StackLayout"
Grid.Row="1"
Padding="30"
BackgroundColor="Black"
HorizontalOptions="Center"
IsVisible="False"
Opacity="0.8"
VerticalOptions="Center">
<ActivityIndicator IsRunning="True" Color="White" />
<Label
FontAttributes="Bold"
Text="Loading..."
TextColor="White" />
</StackLayout>
</Grid>
CodeBehind
private void Button_OnClicked(object sender, EventArgs e)
{
StackLayout.IsVisible = !StackLayout.IsVisible;
}

UI Freeze when Navigation a page to another in xamarin forms

In my application My MainPage Showing Menus and after clicking menu the next page loading very slow and freeze the UI.
This happen when the content page contain a listView with Items.
My Data Page Content a listView with 50 items(Infinite Scrolling First 50 items)
XAML:
<ListView
ItemsSource="{Binding ItemsData}"
SelectedItem="{Binding SelectedItemsData}"
HasUnevenRows="True"
BackgroundColor="White" x:Name="ItemsDataList">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid
Margin="2,0,2,0"
Padding="8"
IsEnabled="{Binding IsEnableItemsData}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30*"/>
<ColumnDefinition Width="30*"/>
<ColumnDefinition Width="30*"/>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding SKU}" Grid.Row="0" Grid.Column="0" HorizontalTextAlignment="Center" VerticalOptions="Center" TextColor="{Binding SKUColor}" FontSize="Small"/>
<Label Text="{Binding OrderNumber}" Grid.Row="0" Grid.Column="1" HorizontalTextAlignment="Center" VerticalOptions="Center" TextColor="Black" FontSize="Small"/>
<Label Text="{Binding CategoryName}" Grid.Row="0" Grid.Column="2" HorizontalTextAlignment="Center" VerticalOptions="Center" TextColor="Black" FontSize="Small"/>
<Label Text="{Binding OrderQuantity}" Grid.Row="0" Grid.Column="3" HorizontalTextAlignment="Center" VerticalOptions="Center" TextColor="Black" FontSize="Small"/>
<Label Text="{Binding Bin}" Grid.Row="0" Grid.Column="4" HorizontalTextAlignment="Center" VerticalOptions="Center" TextColor="Black" FontSize="Small"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Behaviors>
<eventToCommand:EventToCommandBehavior
EventName="ItemSelected"
Command="{Binding ItemsDataSelectedItemChange}"/>
<eventToCommand:EventToCommandBehavior
EventName="ItemAppearing"
Command="{Binding ItemsDataItemAppearing}"/>
</ListView.Behaviors>
</ListView>
ViewModel:
public ObservableCollection<ItemsData> Data
{
get { return _data; }
set
{
_data = value;
RaisePropertyChanged();
}
}
Getting the data from Local Database
Data = GetData(GlobalVariable.BranchId, DataLimit, Offset, SearchText, filterData, "Others", sortData);
How to get rid of this issues?

show datePicker in Xamarin.Forms when click Frame Layout

I am doing an application using Xamarin.Forms. There I need to show a datePicker when clicks on a Frame layout. For that purpose I have done this.
xaml part
<Frame Margin="15,0,15,5" HasShadow="false" OutlineColor="{StaticResource TextColorBlue}" BackgroundColor="White" x:Name="selectDate" HorizontalOptions="FillAndExpand">
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
<DatePicker x:Name="datePicker" IsVisible="false" DateSelected="Handle_DateSelected" TextColor="Maroon" />
<Label Text="Date" FontAttributes="Bold" FontSize="20" HorizontalOptions="Center" TextColor="{StaticResource TextColorBlue}" />
<BoxView HorizontalOptions="FillAndExpand" BackgroundColor="Silver" HeightRequest="1" />
<Grid RowSpacing="1" ColumnSpacing="1" HorizontalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Text="Saturday" FontAttributes="Bold" FontSize="25" Grid.Row="0" Grid.Column="0" HorizontalOptions="Center" VerticalOptions="Center" TextColor="{StaticResource TextColorBlue}" />
<Label Text="May" FontAttributes="Bold" FontSize="25" Grid.Row="0" Grid.Column="1" HorizontalOptions="Center" VerticalOptions="Center" TextColor="{StaticResource TextColorBlue}" />
<Label Text="20" FontAttributes="Bold" FontSize="25" Grid.Row="1" Grid.Column="0" HorizontalOptions="Center" VerticalOptions="Center" TextColor="{StaticResource TextColorBlue}" />
<Label Text="2017" FontAttributes="Bold" FontSize="25" Grid.Row="1" Grid.Column="1" HorizontalOptions="Center" VerticalOptions="Center" TextColor="{StaticResource TextColorBlue}" />
</Grid>
</StackLayout>
<Frame.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1" Tapped="Handle_Tapped_DatePicker" />
</Frame.GestureRecognizers>
</Frame>
cs part
void Handle_Tapped_DatePicker(object sender, System.EventArgs e)
{
Debug.WriteLine("Handle_Tapped_DatePicker");
if (datePicker.IsFocused)
{
Debug.WriteLine("Yes, datePicker is focused");
datePicker.Unfocus();
}
datePicker.Focus();
}
void Handle_DateSelected(object sender, Xamarin.Forms.DateChangedEventArgs e)
{
Debug.WriteLine("e.NewDate: " + e.NewDate.ToString());
}
But nothing happening here. The datePicker is not showing. I am testing on iOS simulator. Please help me on this.
Thankfully I got the answer after some searches.
The thing is that, You need to bring the focus of datePicker through the device main UI thread. I have changed my code like this.
Device.BeginInvokeOnMainThread(() =>
{
if (datePicker.IsFocused)
datePicker.Unfocus();
datePicker.Focus();
});

Resources