Xamarin.Forms Why is my tap command not working? - xamarin.forms

I have this kind of tap command in my carousel view:
<Image
x:Name="img_adPic"
HeightRequest="150"
Aspect="AspectFill"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Source="{Binding thumbnail}">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.TapCommand, Source={x:Reference page}}" CommandParameter="{Binding Path=BindingContext.CurrentIndex, Source={x:Reference page}}"/>
</Image.GestureRecognizers>
</Image>
I gave my contentpage a name :
<ContentPage x:Name="page" >
Now in my class:
public ICommand CarouselItemTapped{ get; set; }
public Page_MainMenuDetail()
{
InitializeComponent();
CarouselItemTapped = new Xamarin.Forms.Command((selectItem) =>
{
});
instance = this;
}
But no matter what I try, the command is NEVER fired. I think i did everything as in the tutorials, why is this not working?
Thank you

You could refer to the code below about how to use the TapCommand. The command would be triggled when you tap on the image.
Xaml:
<ContentPage.Content>
<AbsoluteLayout>
<CarouselView
x:Name="carouselView"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
IndicatorView="indicatorview">
<CarouselView.ItemTemplate>
<DataTemplate>
<Image
x:Name="img_adPic"
Aspect="AspectFill"
HeightRequest="150"
HorizontalOptions="FillAndExpand"
Source="{Binding .}"
VerticalOptions="FillAndExpand">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.TapCommand, Source={x:Reference page}}" />
</Image.GestureRecognizers>
</Image>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<IndicatorView
x:Name="indicatorview"
AbsoluteLayout.LayoutBounds=" 0.5,0.95,100,100"
AbsoluteLayout.LayoutFlags=" PositionProportional"
IndicatorColor=" LightGray"
IndicatorSize=" 10"
SelectedIndicatorColor=" Black" />
</AbsoluteLayout>
</ContentPage.Content>
Code behind:
public partial class Page2 : ContentPage
{
public ICommand CarouselItemTapped { get; set; }
public ICommand TapCommand { get; set; }
public Page2()
{
InitializeComponent();
var list = new List<string>
{
"pink.jpg",
"pink.jpg",
"pink.jpg",
"pink.jpg",
"pink.jpg",
};
carouselView.ItemsSource = list;
//CarouselItemTapped = new Xamarin.Forms.Command((selectItem) =>
//{
//});
//instance = this;
TapCommand = new Command(commandEvent);
this.BindingContext = this;
}
public void commandEvent()
{
}
}

Related

Can't get the CollectionView to Display data in my collection

I am trying to make a collectionView display the items in a collection I have created but that doe snot work at all. I have been looking around to understand the issue but I can't figure it out. Can someone help me out ? See below the XAML code for a custom control I created and following it the code behind in c#
'''
<StackLayout xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CustomControls.CustomControl.DataGrid2"
xmlns:local="clr-namespace:CustomControls.CustomControl"
HeightRequest="500"
WidthRequest="500"
Orientation="Horizontal">
<CollectionView x:Name="c2" ItemsLayout="VerticalList" x:DataType="local:DataGrid2" ItemsSource="{Binding Data2see}" >
<CollectionView.Header>
<StackLayout BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Monkeys"
FontSize="Small"
FontAttributes="Bold" />
</StackLayout>
</CollectionView.Header>
<CollectionView.Footer>
<StackLayout BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Friends of Xamarin Monkey"
FontSize="Small"
FontAttributes="Bold" />
</StackLayout>
</CollectionView.Footer>
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="local:SomeDataExemple2">
<Grid Padding="10" ColumnDefinitions="100,100,100">
<Button Grid.Column="0" Text ="clickmenow2"/>
<Entry Grid.Column= "1" Text="{Binding Name}"/>
<Entry Grid.Column="2" Text="{Binding First_name}"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
namespace CustomControls.CustomControl
{ using System.Collections.Specialized;
using System.Collections.Generic;
using System.Collections;
using System.Collections.ObjectModel;
public partial class DataGrid2 : StackLayout
{
public DataGrid2()
{
Data2see = new Collection<SomeDataExemple2>();
Data2see.Add(new SomeDataExemple2("hamid", "britel"));
Data2see.Add(new SomeDataExemple2("mernissi", "wadie"));
Data2see.Add(new SomeDataExemple2("mhamed", "chraibi"));
Data2see.Add(new SomeDataExemple2("yazid", "alaoui"));
Data2see.Add(new SomeDataExemple2("amine", "gogole"));
Data2see.Add(new SomeDataExemple2("mehdi", "harras"));
InitializeComponent();
//c2.ItemsSource = Data;
}
public Collection<SomeDataExemple2> Data2see
{
get;
set;
}
}
public class SomeDataExemple2
{
public SomeDataExemple2(string name1, string name2)
{
Name = name1;
First_name = name2;
}
public string Name
{
get; set;
}
public string First_name
{
get;
set;
}
}}
.xaml code, you can use ContentPage instead of StackLayout
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp_test.MainPage"
xmlns:local="clr-namespace:MauiApp_test"
HeightRequest="500"
WidthRequest="500">
<CollectionView x:Name="c2" ItemsLayout="VerticalList" >
<CollectionView.Header>
<StackLayout BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Monkeys"
FontSize="Small"
FontAttributes="Bold" />
</StackLayout>
</CollectionView.Header>
<CollectionView.Footer>
<StackLayout BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Friends of Xamarin Monkey"
FontSize="Small"
FontAttributes="Bold" />
</StackLayout>
</CollectionView.Footer>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10" ColumnDefinitions="100,100,100">
<Button Grid.Column="0" Text ="clickmenow2"/>
<Entry Grid.Column= "1" Text="{Binding Name}"/>
<Entry Grid.Column="2" Text="{Binding First_name}"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
.xaml.cs
using System.Collections.ObjectModel;
namespace MauiApp_test;
public partial class MainPage : ContentPage
{
public Collection<SomeDataExemple2> Data2see
{
get;
set;
}
public MainPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
Data2see = new Collection<SomeDataExemple2>();
Data2see.Add(new SomeDataExemple2("hamid", "britel"));
Data2see.Add(new SomeDataExemple2("mernissi", "wadie"));
Data2see.Add(new SomeDataExemple2("mhamed", "chraibi"));
Data2see.Add(new SomeDataExemple2("yazid", "alaoui"));
Data2see.Add(new SomeDataExemple2("amine", "gogole"));
Data2see.Add(new SomeDataExemple2("mehdi", "harras"));
c2.ItemsSource = Data2see
.ToList();
}
public class SomeDataExemple2
{
public SomeDataExemple2(string name1, string name2)
{
Name = name1;
First_name = name2;
}
public string Name
{
get; set;
}
public string First_name
{
get;
set;
}
}
}

Send id dynamically on buttonImg click to delete from fire base xamarin form

I'm trying to delete a doc from firebase data base on click button Img but i don't know how can I send the id of the item into delete service
this is my view file :
<ContentPage.Behaviors>
<xct:EventToCommandBehavior Command="{Binding Appearing}" EventName="Appearing" />
</ContentPage.Behaviors>
<StackLayout>
<Grid HorizontalOptions="CenterAndExpand" >
<Image Source="https://bcckids.org/wp-content/uploads/2016/10/Photo_Main_Slider2.png"
Scale="1.0"
Aspect="Fill"
/>
</Grid>
<ListView
HasUnevenRows="True"
ItemsSource="{Binding Patients}"
SelectedItem="{Binding SelectedPatient, Mode=TwoWay}"
SelectionMode="Single">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid RowDefinitions="Auto,Auto,Auto">
<Frame Style="{StaticResource FrameStyle}"
Margin="15,0,30,0"
>
<StackLayout Orientation="Horizontal" Margin="10,0,20,0" VerticalOptions="Center" HorizontalOptions="Center">
<Image Source="https://www.freeiconspng.com/thumbs/profile-icon-png/profile-icon-9.png" WidthRequest="70" HeightRequest="70"/>
<BoxView
Color="Maroon"
WidthRequest="1"
Margin="5, 0, 10, 0" />
<Label Grid.Row="0" Text="{Binding PatientName}" VerticalOptions="Center" HorizontalOptions="Start" Style="{StaticResource labelView}"/>
<ImageButton Style="{StaticResource DeleteButton}"/>
</StackLayout>
</Frame>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Style="{StaticResource BlusButton}" Clicked="Button_Clicked_1" />
</StackLayout>
and How can i wrote it in viewmodel and call thw service ?
this is my delete service :
public async Task DeletePatient(string ID)
{
await firebaseClient
.Child($"Specalists/406707265/Patients/{ID}")
.DeleteAsync();
}
Code might look something like this:
// Your item model.
public class Patient
{
public string Id { get; set; }
public string PatientName { get; set; }
}
// ... your viewmodel class
{
public ObservableCollection<Patient> Patients { get; set; } = new ObservableCollection<Patient();
}
// YourView.xaml
...
<ListView.ItemTemplate>
...
<ImageButton Style="{StaticResource DeleteButton}" Clicked="ItemImageButton_Clicked" CommandParameter="{Binding .}"/>
// your view's code behind (.xaml.cs):
public partial class YourView ...
{
private async void ItemImageButton_Clicked(object sender, EventArgs e)
{
var patient = (Patient)((ImageButton)sender).CommandParameter;
await DeletePatient(patient.Id);
}
In the .._Clicked method, sender is the ImageButton that was clicked on.
In xaml, CommandParameter="{Binding .}" passes the model item (Patient) to that method.
OR if DeletePatient is in YourViewModel, which is YourView's BindingContext:
// your view's code behind (.xaml.cs):
...
private async void ItemImageButton_Clicked(object sender, EventArgs e)
{
var patient = (Patient)((ImageButton)sender).CommandParameter;
var vm = (YourViewModel)BindingContext;
await vm.DeletePatient(patient.Id);
}

How one ViewModel contains multiple ViewModel xamatin

I have 2 ViewModels (MVVM). I let show 2 as shown, it only shows data 1 ViewModel (the one below).
I put 1 and it shows up as normal.
This is how I display the data
<RefreshView x:DataType="locals:SliderViewModel"
Command="{Binding LoadSliderCommand}"
IsRefreshing="{Binding IsBusy, Mode=OneWay}">
<StackLayout Padding="8,0,8,4"
BindableLayout.ItemsSource="{Binding SliderShowInfos}"
Orientation="Horizontal"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand">
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout x:DataType="model:SliderShowInfo">
<Frame Padding="4"
HasShadow="False"
IsClippedToBounds="True"
BackgroundColor="Transparent">
<StackLayout Orientation="Horizontal">
<Frame Padding="0"
HasShadow="False"
CornerRadius="7"
IsClippedToBounds="True">
<Image Source="{Binding ImagesSlider}">
</Image>
</Frame>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</RefreshView>
<RefreshView x:DataType="locals:ProductViewModel"
Command="{Binding LoadProductCommand}"
IsRefreshing="{Binding IsBusy, Mode=OneWay}">
<StackLayout Padding="8"
Orientation="Horizontal"
BindableLayout.ItemsSource="{Binding ProductInfos}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Frame Padding="5,0"
HasShadow="False"
IsClippedToBounds="True"
BackgroundColor="#fff">
<StackLayout x:DataType="model:ProductInfo">
</StackLayout>
</Frame>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</RefreshView>
This is how I display the data. I'm trying to display product listing and photo listing data. Please give me a solution that can combine 2 ViewModel
Update
SliderViewModel.cs
public class SliderViewModel:BaseSliderViewModel
{
ISliderShowRepository sliderShowRepository = new SliderShowService();
public Command LoadSliderCommand { get; }
public ObservableCollection<SliderShowInfo> SliderShowInfos { get; }
public SliderViewModel()
{
LoadSliderCommand = new Command(async () => await ExecuteLoadSliderCommand());
SliderShowInfos = new ObservableCollection<SliderShowInfo>();
}
public void OnAppearing()
{
IsBusy = true;
}
async Task ExecuteLoadSliderCommand()
{
}
}
ProductViewModel.cs
public class ProductViewModel : BaseProductViewModel
{
IProductRepository productRepository = new ProductService();
public Command LoadProductCommand { get; }
public ObservableCollection<ProductInfo> ProductInfos { get; }
public Command ProductTappedView { get; }
public ProductViewModel(INavigation _navigation)
{
LoadProductCommand = new Command(async () => await ExecuteLoadProductCommand());
ProductInfos = new ObservableCollection<ProductInfo>();
ProductTappedView = new Command<ProductInfo>(OnViewDetailProduct);
Navigation = _navigation;
}
private async void OnViewDetailProduct(ProductInfo prod)
{
await Navigation.PushAsync(new DetailProduct(prod));
}
public void OnAppearing()
{
IsBusy = true;
}
async Task ExecuteLoadProductCommand()
{
IsBusy = true;
try
{
ProductInfos.Clear();
var prodList = await productRepository.GetProductsAsync();
foreach (var prod in prodList)
{
ProductInfos.Add(prod);
}
}
catch(Exception)
{
throw;
}
finally
{
IsBusy = false;
}
}
}
DashboardViewModel.cs
public class DashboardViewModel
{
public SliderViewModel SliderShowVM { get; set; }
public ProductViewModel ProductVM { get; set; }
}
Dashboard.xaml.cs
public Dashboard()
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, true);
BindingContext = new DashboardViewModel();
}
protected override void OnAppearing()
{
base.OnAppearing();
}
You cant just have 2 ViewModels for a single page. Instead, you can create another ViewModel, which will contains those 2 ViewModels that you need.
public class DashboardViewModel
{
public SliderShowViewModel SliderShowVM { get; set; }
public ProductViewModel ProductVM { get; set; }
}
And in dashboard constructor, assign the BindingContext
BindingContext = new DashboardViewModel();
And in your view, bind data like this:
...
<Image Source="{Binding SliderShowVM.ImagesSlider}">
...
BindableLayout.ItemsSource="{Binding ProductVM.ProductInfos}"
...
Also, if you don't need all data from SliderShowViewModel or ProductViewModel on your Dashboard, then you can define the properties that you really need for the dashboard inside DashboardViewModel, and to inject SliderShowViewModel and ProductViewModel instances via constructor (Might not be the best solution, but this way you will keep you view cleaner)
public class DashboardViewModel
{
public string RelevantProperty1 { get; set; }
public int RelevantProperty2 { get; set; }
...
public DashboardViewModel(SliderShowViewModel sliderVm, ProductViewModel productVm)
{
RelevantProperty1 = sliderVm.Something;
RelevantProperty2 = productVm.SomethingElse;
...
}
}
More explicit
DashboardViewModel class: It is a class with two properties of type SliderShowViewModel and ProductViewModel. These properties will store some instances (aka objects) of SliderShowViewModel and ProductViewModel respectively.
Create a DashboardViewModel instance and pass it as BindingContext for your Dashboard View:
public Dashboard()
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, true);
var viewModel = new DashboardViewModel();
// Now we have the viewModel, but there is a problem.
// Remember those two viewModels (SliderShowViewModel and ProductViewModel)?
// Well, those properties are null, we have to provide values for them
// before setting the binding context.
viewModel.SliderViewModel = new SliderViewModel();
viewModel.ProductViewModel = new ProductViewModel();
BindingContext = viewModel;
}
Bind values from DashboardViewModel on our View:
<RefreshView Command="{Binding SliderViewModel.LoadSliderCommand}"
IsRefreshing="{Binding SliderViewModel.IsBusy, Mode=OneWay}">
<StackLayout Padding="8,0,8,4"
BindableLayout.ItemsSource="{Binding SliderViewModel.SliderShowInfos}"
Orientation="Horizontal"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand">
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame Padding="4"
HasShadow="False"
IsClippedToBounds="True"
BackgroundColor="Transparent">
<StackLayout Orientation="Horizontal">
<Frame Padding="0"
HasShadow="False"
CornerRadius="7"
IsClippedToBounds="True">
<Image Source="{Binding SliderViewModel.ImagesSlider}">
</Image>
</Frame>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</RefreshView>
<RefreshView Command="{Binding ProductViewModel.LoadProductCommand}"
IsRefreshing="{Binding ProductViewModel.IsBusy, Mode=OneWay}">
<StackLayout Padding="8"
Orientation="Horizontal"
BindableLayout.ItemsSource="{Binding ProductViewModel.ProductInfos}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Frame Padding="5,0"
HasShadow="False"
IsClippedToBounds="True"
BackgroundColor="#fff">
</Frame>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</RefreshView>
Give it a try and let me know if it works.

OnApplyTemplate doesn't capture the BindingContext of the parent?

In a test project, I'm trying to get the BindingContext of the parent control with template binding,
here, in the MainPage, I have two templates temp1 and temp2
<?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:vm="clr-namespace:MyXam.ViewModels"
xmlns:views="clr-namespace:MyXam.Views"
x:Class="MyXam.Views.MainPage"
x:DataType="vm:MainViewModel">
<ContentPage.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="temp1">
<views:View1/>
</ControlTemplate>
<ControlTemplate x:Key="temp2">
<views:View2/>
</ControlTemplate>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout x:Name="stk">
<Button Text="Switch view" Command="{Binding SwitchViewCommand}"/>
<ContentView x:Name="cv" ControlTemplate="{StaticResource temp2}" VerticalOptions="Start" HorizontalOptions="Center">
<ContentView.Triggers>
<DataTrigger TargetType="ContentView" Binding="{Binding IsView1}" Value="False">
<Setter Property="ControlTemplate" Value="{StaticResource temp2}"/>
</DataTrigger>
<DataTrigger TargetType="ContentView" Binding="{Binding IsView1, Mode=TwoWay}" Value="True">
<Setter Property="ControlTemplate" Value="{StaticResource temp1}"/>
</DataTrigger>
</ContentView.Triggers>
</ContentView>
</StackLayout>
</ContentPage>
I want to get the BindingContext of the MainPage in View2, in the ctor:
SetBinding(BindingContextProperty, new Binding("Parent.BindingContext", source: RelativeBindingSource.TemplatedParent));
but when I try to get its vzlue in the OnApplyTemplate it's null:
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
vm = this.GetValue(BindingContextProperty);
}
However binding is resolved in xaml:
<Label Text="{Binding Name, Source={Reference this}}"/>
I couldn't see the detail of your other code, but you can refer to the following code.
Define a BindableProperty for this Label in xaml.cs and use the Name Property,e.g. x:Name="TestControlView" and binding like this
<Label Text="{Binding Source={x:Reference TestControlView}, Path=TestText}" />
You can check the full demo here.
The main code is like this:
TestControl.xaml.cs(TestControl is a ContentView)
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TestControl : ContentView
{
public static readonly BindableProperty TestTextProperty = BindableProperty.Create(nameof(TestText), typeof(string), typeof(TestControl));
public string TestText
{
get { return (string)GetValue(TestTextProperty); }
set { SetValue(TestTextProperty, value); }
}
public TestControl()
{
InitializeComponent();
}
}
TestControl.xaml
MainPage.xaml
<ListView x:Name="lstView" HorizontalOptions="Fill" HasUnevenRows="True" RefreshAllowed="true" IsPullToRefreshEnabled="true">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame CornerRadius="10" BackgroundColor="White" Margin="0,5,0,5">
<StackLayout Orientation="Horizontal" HorizontalOptions="Center">
<controls:TestControl TestText="{Binding Title}" VerticalOptions="Center"/>
<Label Text="{Binding Type}" FontSize="Medium" TextColor="#F0BB7F" FontAttributes="Bold" VerticalOptions="Center"/>
</StackLayout>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
MainPage.xaml.cs
public partial class MainPage : ContentPage
{
public ObservableCollection<TestModel> veggies { get; set; }
public MainPage()
{
InitializeComponent();
veggies = new ObservableCollection<TestModel>();
veggies.Add(new TestModel { Title = "Tomato", Type = "Fruit" });
veggies.Add(new TestModel { Title = "Zucchini", Type = "Vegetable" });
veggies.Add(new TestModel { Title = "Tomato" , Type = "Vegetable" });
veggies.Add(new TestModel { Title = "Romaine", Type = "Fruit" });
veggies.Add(new TestModel { Title = "Zucchini", Type = "Vegetable" });
lstView.ItemsSource = veggies;
BindingContext = this;
}
}

Xamarin Forms Prism Problem with navigation within a listview

As the title indicates I have problems with navigation.
I have a page called EvaluationPage, It contains four ContentPage inside has a Grid.
On this level I have a button (FAB) and CollectionView.
The CollectionView has Itemsource with ObservableCollection
The FAB open ReferenciaLaboralPage in mode Modal. If the form that has this page is filled out and the save button is clicked, add an item to the observable collection of the itemsource. It is done by Singleton.
The collectionview updates the new item, the item has a tap gesture that executes a command to open the page that was previously opened in modal mode and this is where it is not working. The command does run but the NavigateAsync does not display the page.
XAML EvaluacionPage
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<CollectionView ItemsSource="{Binding ReferenciasPersonales}" EmptyView="No existen referencias" VerticalOptions="FillAndExpand" Grid.Row="0">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical"
ItemSpacing="0" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Grid>
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding SelectedCommand}" NumberOfTapsRequired="1" />
</Grid.GestureRecognizers>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<pancake:PancakeView Grid.Column="0">
<Label Text="{Binding Letter}" TextColor="White" />
</pancake:PancakeView>
<StackLayout Grid.Column="1" >
<Label Text="{Binding Nombre}" Style="{StaticResource RobotoBold}" FontSize="16" />
<Label Text="{Binding TipoReferencia}" Style="{StaticResource RobotoRegular}" />
<Label Text="{Binding Telefono}" Style="{StaticResource RobotoRegular}" />
<Label Text="{Binding TiempoConocerlo}" Style="{StaticResource RobotoRegular}" />
</StackLayout>
<Label Grid.Column="2" Text="{Binding FechaRegistro, StringFormat='{0:dd/MM/yyyy}'}" />
</Grid>
<BoxView HorizontalOptions="FillAndExpand" BackgroundColor="LightGray" HeightRequest="1" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<pancake:PancakeView Elevation="10" VerticalOptions="End" HorizontalOptions="End" Margin="0,0,20,22" HeightRequest="50" WidthRequest="50" CornerRadius="25" Grid.Row="0">
<pancake:PancakeView.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OpenReferenciaCommand}" NumberOfTapsRequired="1" />
</pancake:PancakeView.GestureRecognizers>
<Label Text="" TextColor="White" Style="{StaticResource IconStyleSolid}" VerticalOptions="Center" HorizontalOptions="Center" />
</pancake:PancakeView>
</Grid>
CODE EvaluacionPageViewModel
public DelegateCommand OpenReferenciaCommand => _openReferenciaCommand ?? (_openReferenciaCommand = new DelegateCommand(ShowReferenciaPersonal));
async void ShowReferenciaPersonal()
{
await _navigationService.NavigateAsync("ReferenciaPersonalPage", useModalNavigation: true);
}
// Add item to datasource
public void AddReferenciaPersonal(ReferenciaPersonalItemViewModel item)
{
if (item.IdReferencia == 0)
{
ReferenciasPersonales.Add(item);
}
else
{
ReferenciasPersonales.Remove(ReferenciasPersonales.Where(w=>w.IdReferencia == item.IdReferencia).Single());
ReferenciasPersonales.Add(item);
ReferenciasPersonales = ReferenciasPersonales;
}
}
CODE ReferenciaPersonalPageViewModel
public class ReferenciaPersonalPageViewModel : ViewModelBase
{
private readonly INavigationService _navigationService;
private readonly IApiService _apiService;
private readonly IDialogService _dialogService;
private DelegateCommand _closeCommand;
private DelegateCommand _saveCommand;
private string _nombre;
private ReferenciaPersonalItemViewModel _item;
private bool _isRunning;
private bool _isEnable;
public ReferenciaPersonalPageViewModel(INavigationService navigationService, IApiService apiService, IDialogService dialogService) : base(navigationService)
{
_navigationService = navigationService;
_apiService = apiService;
_dialogService = dialogService;
_item = new ReferenciaPersonalItemViewModel(navigationService);
}
public string Nombre
{
get => _nombre;
set => SetProperty(ref _nombre, value);
}
public bool IsRunning
{
get => _isRunning;
set => SetProperty(ref _isRunning, value);
}
public bool IsEnable
{
get => _isEnable;
set => SetProperty(ref _isEnable, value);
}
#endregion
#region Commands
public DelegateCommand CloseCommand => _closeCommand ?? (_closeCommand = new DelegateCommand(ExecuteCloseCommand));
public DelegateCommand SaveCommand => _saveCommand ?? (_saveCommand = new DelegateCommand(ExecuteSaveCommand));
#endregion
#region Metodos
async void ExecuteCloseCommand()
{
await _navigationService.GoBackAsync();
}
private async void ExecuteSaveCommand()
{
IsRunning = true;
IsEnable = false;
_item.Direccion = Direccion;
_item.Nombre = Nombre;
_item.Telefono = Telefono;
_item.TiempoConocerlo = TiempoConocerlo;
_item.TipoReferencia = TipoReferencia;
_item.FechaRegistro = _item.IdReferencia > 0 ? _item.FechaRegistro : DateTime.Now.ToLocalTime();
EvaluacionPageViewModel.GetInstance().AddReferenciaPersonal(_item);
IsRunning = false;
IsEnable = true;
await _navigationService.GoBackAsync();
}
#endregion
public override void OnNavigatedTo(INavigationParameters parameters)
{
base.OnNavigatedTo(parameters);
if (parameters.ContainsKey("item"))
{
_item = parameters.GetValue<ReferenciaPersonalItemViewModel>("item");
Nombre = _item.Nombre;
Direccion = _item.Direccion;
Telefono = _item.Telefono;
TiempoConocerlo = _item.TiempoConocerlo;
TipoReferencia = _item.TipoReferencia;
}
}
}
CODE ReferenciaPersonalItemViewModel
public class ReferenciaPersonalItemViewModel : Referencia
{
private readonly INavigationService _navigationService;
private DelegateCommand _selectedCommand;
public ReferenciaPersonalItemViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
}
public DelegateCommand SelectedCommand => _selectedCommand ?? (_selectedCommand = new DelegateCommand(ShowItem));
private async void ShowItem()
{
await _navigationService.NavigateAsync("ReferenciaPersonalPage", useModalNavigation: true);
}
}
When I click on the (fab) button to open the modal the
NavigationUriPath before the NavigateAsync is:
/MainMasterDetailPage/NavigationPage/HomePage/ItineraryPage/EvaluationPage
When I click on the collectionview item to open modal the
NavigationUriPath before the NavigateAsync is:
/MainMasterDetailPage/NavigationPage/HomePage/ItinerarioPage/EvaluacionPage/ReferenciaPersonalPage?useModalNavigation=true
If I put the absolute path if it shows the page but shows it with a
navigation Bar

Resources