Xamarin.Forms conflict between PanGesture and TapGesture - c#

This is my XAML 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="App1.Views.ItemsPage"
Title="{Binding Title}"
x:Name="BrowseItemsPage">
<StackLayout>
<StackLayout.GestureRecognizers>
<PanGestureRecognizer PanUpdated="PanGestureRecognizer_PanUpdated"/>
</StackLayout.GestureRecognizers>
<Label Text="111111111111111111111111111111">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</Label.GestureRecognizers>
</Label>
</StackLayout>
</ContentPage>
End the behind-code
private void PanGestureRecognizer_PanUpdated(object sender, PanUpdatedEventArgs e)
{
Console.WriteLine($"{DateTime.Now} pan");
}
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
DisplayAlert("Alert", "You have been alerted", "OK");
}
When I run above code, at the first pan gesture I make a Pan on the Label and swipe down the PanGestureRecognizer_PanUpdated is NOT fired. It's only fired when I tap outside the Label then start a pan gesture on the Label.
Then I remove the TapGestureRecognizer's Label, and make a Pan on the Label and swipe down the PanGestureRecognizer_PanUpdated is fired.
It's conflict between Tap vs Pan gesture ?
P/s: I want to make a list swipe up/down-able (the container, in this case is StackLayout), and the items are clickable. I'm not using the ListView, because I'm making custom library

This is the expected results . When you make the pan on label,the first register object is the Label , not the StackLayout .So the event will never been called .
Solution: You can put the StackLayout in a ScrollView . And add the PullToRefresh event on it .
Here is a plugin which can add Pull to Refresh to ScrollView .
<controls:PullToRefreshLayout
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsBusy}"
RefreshColor="Blue">
<ScrollView
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<StackLayout>
<Label Text="111111111111111111111111111111">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</Label.GestureRecognizers>
</Label>
</StackLayout>
</ScrollView>
</controls:PullToRefreshLayout>

Related

Why does my ImageButton not work in AbsoluteLayout? In .NET MAUI

I have an ImageButton in a Grid. Around the ImageButton, I have an <AbsoluteLayout>. When clicking, nothing happens or the method is not executed.
My XAML:
<VerticalStackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="#24D4A3">
<Grid BackgroundColor="White">
<AbsoluteLayout>
<ImageButton
Clicked="CreateNote"
Source="add.png"
BorderColor="#2b3c3c"
BorderWidth="0"
BackgroundColor="#34A4EB"
CornerRadius="35"
WidthRequest="70"
HeightRequest="70"
AbsoluteLayout.LayoutBounds="313,625"
Padding="2,0,0,0"/>
</AbsoluteLayout>
</Grid>
</VerticalStackLayout>
The method CreateNote:
private async void CreateNote(object sender, EventArgs e)
{
await Shell.Current.GoToAsync("//CreateNote");
}
I would be grateful for any help!!
I copied your code to my app and did a test,I found the space above your ImageButton is so large that I couldn't see it on my emulator.
So I added a ScrollView out of the VerticalStackLayout.Then I could see the ImageButton after I scrolled my page. And I could also trigger the clicked event ImageButton_Clicked of ImageButton .
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1226.MainPage">
<ScrollView>
<VerticalStackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="#24D4A3">
<Grid BackgroundColor="White">
<AbsoluteLayout>
<ImageButton
Clicked="ImageButton_Clicked"
Source="icon.png"
BorderColor="#2b3c3c"
BorderWidth="0"
BackgroundColor="#34A4EB"
CornerRadius="35"
WidthRequest="70"
HeightRequest="70"
AbsoluteLayout.LayoutBounds="313,625"
Padding="2,0,0,0"/>
</AbsoluteLayout>
</Grid>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
Function ImageButton_Clicked
private void ImageButton_Clicked(object sender, EventArgs e)
      {
            System.Diagnostics.Debug.WriteLine(" click this ImageButton ");
      }

Xamarin forms select carousel item

I am learning Xamarin, I would like to get the value of the carousel item selected. I cannot add ItemSelected as in a listview.
Here my Xaml code :
<CarouselView x:Name="NewsList" >
<CarouselView.ItemTemplate >
<DataTemplate>
<StackLayout>
<Frame HasShadow="True"
BorderColor="DarkGray"
CornerRadius="5"
Margin="20"
HeightRequest="300"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand">
<StackLayout>
<Label Text="{Binding NewsName}"
FontAttributes="Bold"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Image Source="{Binding NewsImageUrl}"
Aspect="Fill"
HeightRequest="150"
WidthRequest="150"
HorizontalOptions="Center" />
<Label Text="{Binding ProviderAndDate}"
HorizontalOptions="Center" />
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
Here is the function I would like to use once my item is selected: Get the value of NewsName and ProviderAndDate
private void OnFrameTapped(object sender, EventArgs e)
{
Console.WriteLine("SelectedNewsName" + "SelectedNewsProviderAndDate");
}
Thanks for your help
CarouselView is sort of a different control when it comes to visualization and events than a ListView so you will have to come up with sort of a different solution too
The easiest way to do something similar to a selected item event here would need customization from your side to add the event in.
A good workaround would be just using the CurrentItem property or passing a CommandParameter on the Tap of a Frame!
<StackLayout>
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding CarouselItemTapped,Source={x:Reference currentPage}}" CommandParameter="{Binding .}"/>
</StackLayout.GestureRecognizers>
<Frame ...... />
And then give your current contentpage a x:Name
<ContentPage ..... X:Name="currentPage"
Now in your xaml.cs
Public ICommand CarouselItemTapped{ get; set; }
In the Constructor:
CarouselItemTapped= new Xamarin.Forms.Command((selectItem)=>{//Perform action here});
Feel free to get back if you have questions
More about Commands: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/commanding
More about CarouselView: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/carouselview/
Late but it might help someone. The one who is using BindingContext to bind the data, they can get tapped model as shown below.
private void OnFrameTapped(object sender, EventArgs e)
{
var frame = sender as Frame;
var x = frame.BindingContext as YOURMODEL;
}

Xamarin RotateTo is not rotating from center ( images or views ) on UWP

Xamarin.Forms Version: 4.2.0.709249 ( latest ).
UWP Target: 16299
I am trying to rotate images and views, and I've tried most of I've been figuring to fix the issue without luck.
On Android images and views are rotating properly from the center, but on UWP there's a displacement and it's just at center each 4 rotations. Then things like spinners are rendering really ugly.
C#
using System.ComponentModel;
using Xamarin.Forms;
namespace CheckSpinner
{
// Learn more about making custom code visible in the Xamarin.Forms previewer
// by visiting https://aka.ms/xamarinforms-previewer
[DesignTimeVisible(false)]
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
protected override async void OnAppearing()
{
base.OnAppearing();
while (true)
{
await Spinner.RotateTo(360, 36000, Easing.Linear);
await Spinner.RotateTo(0, 0);
}
}
}
}
XAML
<?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="CheckSpinner.MainPage">
<StackLayout
Padding="16">
<!-- Place new controls here -->
<Label
Text="Check that the square is not spinning from the center properly!"
HorizontalTextAlignment="Center"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"
/>
<StackLayout
Orientation="Horizontal"
VerticalOptions="StartAndExpand"
HorizontalOptions="Center">
<AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="Blue" x:Name="absoluteLayout">
<BoxView
x:Name="Spinner"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds=".5, .5"
HeightRequest="300"
WidthRequest="300"
Color="Aqua" />
<BoxView
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds=".5, .5"
HeightRequest="8"
WidthRequest="8"
Color="Red" />
</AbsoluteLayout>
</StackLayout>
</StackLayout>
</ContentPage>
Sample project showing issue
Gif showing the bad rotation on UWP
P.D.:
I've tried with many layout combinations and same happens.
On Android it's rotating properly.

Xamarin No property, bindable property, or event found for 'ToolbarItems'

What i was trying to do is adding toolbar to a content page.
after adding this code under StackLayout
<ContentPage.ToolbarItems>
<ToolbarItem Icon="plus.png"/>
</ContentPage.ToolbarItems>
for additional info. if i put the upper code in same position as top StackLayout the toolbar just wont appear.
i faced an error and could't find same error any where else.
this is my xaml file content.
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
xmlns:ic="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin.Abstractions"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="EodiRoad.SocialPage">
<StackLayout>
<ContentPage.ToolbarItems>
<ToolbarItem Icon="plus.png"/>
</ContentPage.ToolbarItems>
<ListView x:Name="socialPostsListView" HasUnevenRows="true" IsPullToRefreshEnabled="true">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" Padding="5">
<StackLayout Orientation="Horizontal" Padding="5">
<ic:CircleImage
x:Name="userProfileImage"
HeightRequest="50"
WidthRequest="50"
Aspect="AspectFill"
Source="{Binding post.uploader.userProfile.userThumbnail}"
/>
<Label Text="{Binding post.uploader.username}"/>
</StackLayout>
<Image
x:Name="postImage"
Source="{Binding post.image}"
Aspect="AspectFill"
/>
<StackLayout Orientation="Horizontal">
<Button Text="like"/>
<Button Text="share"/>
</StackLayout>
<StackLayout Orientation="Vertical" HorizontalOptions="StartAndExpand">
<Label Text="{Binding post.content}"/>
<Label Text="{Binding post.uploadedTime}" TextColor="Gray"/>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
and this is the error.
No property, bindable property, or event found for 'ToolbarItems'
and the full error.
/Users/UZU/Google Drive/Apps/EodiRoad/EodiRoadXamarin/EodiRoad/EodiRoad/EodiRoad.Views.SocialPage.xaml(5,5): Error: Position 13:5. No property, bindable property, or event found for 'ToolbarItems' (EodiRoad)
what am i doing wrong here? and whats that error about, and how to fix it?!
i believe in you guys.
This snippet
<ContentPage.ToolbarItems>
<ToolbarItem Icon="plus.png"/>
</ContentPage.ToolbarItems>
can mean 2 things, depending on context:
Let's set the ToolbarItems property (or ToolbarItemsProperty BindableProperty) of this ContentPage (if the parent node is a ContentPage, or
Let's set the Attached BindableProperty ContentPage.ToolbarItemsProperty to the current BindableObject.
As you are using this in a StackLayout, this is interpreted as the 2nd, but such a property doesn't exists ! so it fails.
Place that directly in the ContentPage and it'll work like a charm
<ContentPage ...>
<ContentPage.ToolbarItems>
<ToolbarItem Icon="plus.png"/>
</ContentPage.ToolbarItems>
<StackLayout .../>
</ContentPage>
About the ToolbarItems not appearing, depending on the platform you are running on, it might require the ContentPage to be packed in a NavigationPage.
You need to add the ToolbarItems outside of the StackLayout Try this:
<ContentPage
xmlns:ic="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin.Abstractions"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="EodiRoad.SocialPage">
<ContentPage.ToolbarItems>
<ToolbarItem Icon="plus.png"/>
</ContentPage.ToolbarItems>
<StackLayout>
<!-- Your Content -->
</StackLayout>
</ContentPage>

TableView Viewcell Tapped action

How do I make use of the Tapped action in the ViewCell to navigate to other page?
Xmal codes
<TableView Intent="Settings" HasUnevenRows="true" VerticalOptions="StartAndExpand" BackgroundColor="White" >
<TableRoot>
<TableSection>
<ViewCell Height="100" Tapped="OnProfileClicked">
<ViewCell.View>
<StackLayout Orientation="Horizontal" Padding="5,2,5,2" BackgroundColor="White" >
<Image x:Name="ImgProfile" HeightRequest="100"/>
<Label x:Name="btnName" VerticalOptions="Center" TextColor="Black" FontSize="20"/>
<Label Text="> " FontSize="15" HorizontalOptions="EndAndExpand" VerticalOptions="Center"/>
</StackLayout>
</ViewCell.View>
</ViewCell>
</TableSection>
</TableRoot>
</TableView>
CS File
public void onProfileTapped()
{
Navigation.PushAsync(new Clubs());
}
so there are a couple things that are wrong with your code.
1.) You wrote Tapped=OnProfileClicked but the method you actually made is called onProfileTapped(), this is a mismatch
2.) The parameters for your item tapped event are wrong, most Xamarin events contain a sender and eventArgs.
Here's how you can fix your code to make it work:
void OnProfileClicked (object sender, System.EventArgs e) { //your code}
Also, tip, when you push a page using Navigation. You might want mark the method as async and await the action to make sure it's a smooth transition.

Categories

Resources