Xamarin Forms (IOS, Droid)- PanGestureRecognizer for whole form - xamarin.forms

I am writing a cross-platform application (IOS, Droid) and like to catch all the Pan Gestures.
The problem is that I have (buttons + Webview) on my interface. none of them catch the "Pan Gestures". If the user swipe over the button I catch only the click event.
<Grid VerticalOptions="Fill" HorizontalOptions="Fill">
<Grid.GestureRecognizers>
<PanGestureRecognizer PanUpdated="OnPanUpdated" />
</Grid.GestureRecognizers>
<Button text="Test" />
<Webview />
</Grid>
void OnPanUpdated(object sender, PanUpdatedEventArgs e)
{
//My code here
}
It should detect the Pan event anywhere, but it did not do with the Webview and button.
Idea
Can I put a transparent control over the form that can allow click events to go through, but at the same time can catch the Pan event only?
I tried to use custom render and nothing help.
Thanks in advance

Related

Xamarin.Forms TapGestureRecognizer on listview not working when there are elements

I have a ListView I am using for chat messages. In order to dismiss the keyboard, I am listening for a tap gesture ANYWHERE inside the ListView. If the ListView has items, it never fires, but if there are no items, it fires just fine. What am I doing wrong?
I have also tried XamarinCommunityToolkit TouchEvents, but that won't work either. I can only get that to fire on the ContentView as a whole.
public LiveEventChat() {
InitializeComponent();
var listviewgesture = new TapGestureRecognizer();
listviewgesture.Tapped += Listviewgesture_Tapped;
messageList.GestureRecognizers.Add(listviewgesture);
}
You can add ItemTapped event to ListView, it will be triggered when ListView is clicked.
Here is the xaml code:
<StackLayout>
<ListView x:Name="mytest" ItemTapped="mytest_ItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding .}"></Label>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
Here is cs code:
private void mytest_ItemTapped(object sender, ItemTappedEventArgs e)
{
//do something
}
Using the above code, whenever you click on the ListView, the event will be triggered.

Xamarin.Forms SwipeView OnClick Event Handler

I'm experimenting with the new SwipeView controls in Xamarin forms 4.4, and have been going through the FavFighters example (Code on Github) and think it's brilliant.
I'm able to add a Swipe right/left gesture as I wanted, but I can't find out how to add an OnClick event to an item in the list, in a Master/Detail type of project. I was hoping to use the swipe left/right actions for shortcuts, but want the user to click on the listed item to drill-into it further.
Is there a way of adding an OnClick (or an onSelected) event to the SwipeView items?
Yes you can definitely go with Xamarin.Forms.Effects which allows you implement different effects with native features.
You can refer this: https://github.com/mrxten/XamEffects it shows how to have tap effect, long tap effect, which will be helpful in your case [you can do that even without installing third party plugin].
Do you want to achieve the result like following GIF.
If you want to add the click event for your SwipeView. you just add the GestureRecognizers in your swipeView like following code.
<SwipeView>
<SwipeView.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</SwipeView.GestureRecognizers>
<SwipeView.LeftItems>
<SwipeItems>
<SwipeItem Text="Favorite"
BackgroundColor="LightGreen"
Invoked="SwipeItem_Invoked" />
<SwipeItem Text="Delete"
BackgroundColor="LightPink"
Invoked="SwipeItem_Invoked_1" />
</SwipeItems>
</SwipeView.LeftItems>
<!-- Content -->
<Grid HeightRequest="60"
WidthRequest="300"
BackgroundColor="LightGray">
<Label Text="Swipe right"
HorizontalOptions="Center"
VerticalOptions="Center" />
</Grid>
</SwipeView>
In the background code.
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
Navigation.PushModalAsync(new Page1());
}

How to hide keyboard of entry inside the listview in xamarin.forms.ios

How to hide keyboard of an entry.I have an entry inside of a listview. When I tap on the entry the keyboard is showing, but the keyboard is not hiding when I tap outside. The listview row is adding dynamically so in first case only one row is in it.Android is working perfectly. But in iOS this issue is there.
Please help me
<ListView HorizontalOptions="FillAndExpand" ItemsSource="_list"
VerticalOptions="FillAndExpand"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation=Horizontal>
<Label Text="Name"/>
<Entry PlaceHolder="Name" />
<Label Text="+" FontSize="50">
<Label .GestureRecognizers>
<TapGestureRecognizer Tapped="AddMore_Tapped"
CommandParameter="{Binding Id}"/>
</Label .GestureRecognizers>
</Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Xaml.CS
private async void AddMore_Tapped(object sender, EventArgs e)
{
_list.Add("1");
}
here is my code,
first time only one row is there after clicking the "+" icon one row will be added to listview. So in the case of listview with one row, when I tap on that entry the keyboard is showing, but when I tap outside it's not hiding.It's hiding only when I tap on the first row.
You could update your Xamarin.forms version to the last.
In ios, the keyboard would hide when you click on the other place of listview except the “+” label.
Or you could use custom renderer to make the done button, to hide the keyboard manually.
CustomEntry:cs
public class CustomEntry : Entry
{
}
CustomEntryRenderer.cs
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace HidekeyboardOfEntryDemo.iOS
{
public class CustomEntryRenderer : EntryRenderer
{
private UITextField textField;
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
textField = (UITextField)this.Control;
textField.ReturnKeyType = UIReturnKeyType.Done;
}
}
}
Usage
<hidekeyboardofentrydemo:CustomEntry Placeholder="Name" />
You could download HidekeyboardOfEntryDemo project from GitHub for reference.
https://github.com/WendyZang/Test.git

Xamarin.forms: button event handler calling a method in a parent class using xaml

Can this be done? What I am after is something like this:
<StackLayout x:Name="AParent">
<StackLayout>
<Button Text="Click me!" Clicked="AParent.OnButtonClicked()" />
</StackLayout>
</StackLayout>
and in the codebehind for AParent:
async void OnButtonClicked(object sender, EventArgs e)
{
Debug.WriteLine("Click!");
}
I'm not sure if I understand you correctly, but I think what you're after is this. Specify your Button like this:
<Button Text="Click me!" Clicked="OnButtonClicked" />
And in your code-behind you can do this:
void OnButtonClicked(object sender, EventArgs e)
{
Debug.WriteLine("Click!");
}
It doesn't matter that the Button is nested inside other elements. These are not parent classes, but simply parents in the visual tree. All the objects are still in the same class and can be reached through the code-behind of that page.

How to identify what itemSelected during button click inside ListBox ItemTemplate

I have an ItemTemplate that contains a simple button. When I click this button I need a way to identify the row clicked to pull out the item bound to the listbox.
XAML
<ListBox Name="DemoBox" SelectionChanged="listBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="150">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="400"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Height="120" Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0"
Text="{Binding SomeObjProperty}"/>
</Grid>
<Grid Height="120" Grid.Column="1" Margin="0,-12,0,0">
<Button Click="ShowStuffOnMap_Click">
<Button.Background>
<ImageBrush ImageSource="images/arrow.png"/>
</Button.Background>
</Button>
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
click handler
private void ShowStuffOnMap_Click(object sender, RoutedEventArgs e)
{
//sender is the button so ...
}
Thank you in advance
Why do you have Button with a click event inside a ListBox with a SelectionChanged event? This makes up for some scary UX, if they have different actions!
The normal approach is to have a databound ListBox, and then use the SelectionChanged event to read out the selected item.
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listBox = sender as ListBox;
var selectedItem = listBox.SelectedItem as MyDataBoundType;
if (selectedItem != null)
{
// do stuff
}
// if you use the ListBox for navigation, set the SelectedIndex to -1
// listBox.SelectedIndex = -1;
}
But if you really really want to do it, you need to use the Tag property.
<Button Click="ShowStuffOnMap_Click" Tag="{Binding}">
And then in your event handler:
private void ShowStuffOnMap_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
var selectedItem = button.Tag as MyDataBoundType;
}
But I still think your approach here is wrong, and stands for bad user experience, as the normal approach to a list is that the entire line in the list, is one-selection only.
The best way to do this is to have some unique identifier in the template itself. For example, you have a TextBlock - give it a unique name, and when the button is pressed, search the secondary grid for the TextBlock with the identifier and read its Text property.

Resources