Dealing with iOS and Android diferences on xamarin.forms - android

Im building a cross platform app. I have just finished my prototype and it works well on android. However, i started testing the prototype on iOS and i am getting some problems that i dont know how to solve and i wish you guys can help me.
So, for now i have 2 problems:
1st > On android button inside listview is recognizing its event handler/command and firing the event. But on iPhone, its being ignored.
2nd > IPhone seems to be adding some icons to my view that didnt apear on android and they have no utility for me. Is there any way to remove them ?
Xaml:
<local:CustomListView.ItemTemplate>
<DataTemplate>
<local:CustomViewCell>
<ContentView Padding="10,10,10,0">
<Frame BackgroundColor="{Binding Cor}" CornerRadius="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="15"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="2" Image="{Binding ImageSource}" Rotation="90" BackgroundColor="Transparent" HorizontalOptions="EndAndExpand"
CommandParameter="{Binding .}" Command="{Binding BindingContext.CommandoOpcoes, Source={x:Reference tarefas}}"/>
<Image Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Scale="0.7" Source="{local:ImageResource x.Images.location1.png}"/>
<Label Grid.Row="0" Grid.Column="1" Grid.RowSpan="2" Grid.ColumnSpan="2" Text="{Binding Titulo}" FontAttributes="Bold" FontSize="Medium" VerticalTextAlignment="Center"/>
<Image Grid.Row="2" Grid.Column="0" Scale="0.7" Source="{local:ImageResource x.Images.clock.png}"/>
<Label Text="{Binding Duracao}" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" VerticalTextAlignment="Center"/>
<Image Grid.Row="3" Grid.Column="0" Scale="0.7" Source="{local:ImageResource x.Images.location2.png}"/>
<Label Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding ObjectivoAno}" VerticalTextAlignment="Center"/>
</Grid>
</Frame>
</ContentView>
View Model :
public Command CommandoOpcoes
{
get;
private set;
}
/*
* Menu de um item da lista clicado
* Apresenta opções de editar, apagar e marcar uma tarefa como concluída
*/
private void MostraOpcoes(object t)
{
var Tarefa = t as Tarefa;
async void apagarTarefa()
{
var res = await App.Current?.MainPage?.DisplayAlert(AppResource.Confirmacao, AppResource.Apagar, AppResource.Nao, AppResource.Sim);
if (res == false)
{
Tarefas.Remove(Tarefa);
NTarefas--;
}
}
async void editarTarefa()
{
var page = new EditarTarefa()
{
BindingContext = Tarefa
};
if (PopupNavigation.Instance.PopupStack.Count > 0)
await PopupNavigation.Instance.PopAllAsync(false);
await PopupNavigation.Instance.PushAsync(page, true);
}
void completarTarefa()
{
if (Tarefa.Cumprido == false)
{
Tarefa.Cumprido = true;
Tarefa.Cor = Color.FromHex("#E5F2E5");
NTarefasConcluidos++;
if (NTarefasNaoConcluidos > 0)
NTarefasNaoConcluidos--;
}
else
{
Tarefa.Cumprido = false;
Tarefa.Cor = Color.FromHex("#FFE5E5");
NTarefasNaoConcluidos++;
if (NTarefasConcluidos > 0)
NTarefasConcluidos--;
}
}
ActionSheetConfig config = new ActionSheetConfig();
if (Tarefa.Cumprido)
config.Add(AppResource.nCompleto, completarTarefa, "completo.png");
else
{
config.Add(AppResource.EditarTarefa, editarTarefa, "edit.png");
config.Add(AppResource.Completo, completarTarefa, "completo.png");
}
config.SetDestructive(AppResource.ApagarTarefa, apagarTarefa, "delete.png");
config.UseBottomSheet = true;
UserDialogs.Instance.ActionSheet(config).Dispose();
UserDialogs.Instance.ActionSheet(config);
}
public TarefasViewModel()
{
Tarefas = new ObservableCollection<Tarefa>(App.tarefas.Where(x => x.Data == DateTime.Today).ToList());
NTarefas = Tarefas.Count;
NTarefasConcluidos = Tarefas.Where(x => x.Cumprido == true).Count();
NTarefasNaoConcluidos = Tarefas.Where(x => x.Cumprido == false).Count();
CommandoOpcoes = new Command(q => MostraOpcoes(q));
}
Image of view on iOS with the undesired icons :
https://imgur.com/VTXRXNh
Image on android :
https://imgur.com/v6dfkEW

So, i found the solution. It was quite easy.On ViewCell, the StyleId property can add disclosure buttons to iOS lists.
To not have any of these disclosure buttons, i just made :
<ViewCell StyeleId="none">...</ViewCell>

Related

Load Embedded Resources as Images in MAUI

I created a simple program with MAUI to load 2 images, specified as Embedded Resources.
This is the MainPage:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Surprise.MainPage">
<ScrollView>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="550"/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<VerticalStackLayout x:Name="ImageContainer"
Grid.Row="0"
HeightRequest="500"
VerticalOptions="Center"
HorizontalOptions="Center" />
<Grid Grid.Row="1"
HorizontalOptions="Center"
HeightRequest="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Text="Image1"
Grid.Column="0"
Clicked="OnImage1ButtonClicked" />
<Button Text="Image2"
Grid.Column="2"
Clicked="OnImage2ButtonClicked" />
</Grid>
</Grid>
</ScrollView>
</ContentPage>
and this is its code behind:
public partial class MainPage : ContentPage
{
private readonly Image _image1;
private readonly Image _image2;
public MainPage()
{
InitializeComponent();
_image1 = new Image()
{
Source = ImageSource.FromResource("Surprise.Resources.Images.image1.jpeg"),
VerticalOptions = LayoutOptions.Center,
HeightRequest = 500
};
_image2 = new Image()
{
Source = ImageSource.FromResource("Surprise.Resources.Images.image2.jpg"),
VerticalOptions = LayoutOptions.Center,
HeightRequest = 500
};
}
private void OnImage1ButtonClicked(object sender, EventArgs e)
{
ImageContainer.Children.Clear();
ImageContainer.Children.Add(_image1);
}
private void OnImage2ButtonClicked(object sender, EventArgs e)
{
ImageContainer.Children.Clear();
ImageContainer.Children.Add(_image2);
}
}
On Windows it works correctly.
On Android sometimes the images are loaded in wrong order or even the same image is loaded when I press each button.
Is it a MAUI bug or I'm missing something?
Thanks in advance.
Well, there are some changes that were made with Maui projects, we now have Maui-specific build actions that you can use to specify to your project/solution what the type of a certain file is.
In your Scenario, you should use the MauiImage build action then just uses the name of the file as shown here: https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/image#load-a-local-image should be enough to fix your issue

Xamarin.Android Camera Permissions with ZXing.Net.Mobile only works after app restart

I am using ZXing.Net.Mobile in a Xamarin.Forms project. It works fine on iOS, but on Android, the first time I use the scanner, I get the camera permissions popup, and grant them.
There is no image from the camera immediately after the permissions. If I quit the app and re-launch, the camera works fine from that point forward. How can I get it to work right away? Even if I close my view, dispose and re-initialize it, it still doesn't work until the app restarts.
Here is relevant code:
public partial class CEUScanModalPage : ContentPage, INotifyPropertyChanged {
private bool _isScanning;
public CEUScanModalPage() {
InitializeComponent();
IsScanning = false;
BindingContext = this;
Indicator.Start();
}
public bool IsScanning {
get {
return _isScanning;
}
set {
_isScanning = value;
OnPropertyChanged();
}
}
private async void OnCloseButtonClicked(object sender, EventArgs args) {
await Navigation.PopModalAsync();
}
protected override void OnAppearing() {
base.OnAppearing();
IsScanning = true;
}
protected override void OnDisappearing() {
base.OnDisappearing();
_scanView.OnScanResult -= Handle_OnScanResult;
_scanView.IsAnalyzing = false;
_scanView.IsScanning = false;
ParentGrid.Children.Remove(_scanView);
_scanView = null;
}
public async void Handle_OnScanResult(Result result) {
IsScanning = false;
}
}
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:local="clr-namespace:BehaviorLive" xmlns:grial="clr-namespace:UXDivers.Grial;assembly=UXDivers.Grial" xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms" xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations" xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
x:Class="BehaviorLive.Views.CEUScanModalPage"
NavigationPage.HasNavigationBar="False"
Style="{ StaticResource MainMenuOrModalBackgroundStyle }">
<ContentPage.Resources>
<ResourceDictionary
Source="/Styles/TabControl/SimpleTabResources.xaml" />
</ContentPage.Resources>
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition
Height="145" />
<RowDefinition
Height="*" />
</Grid.RowDefinitions>
<Grid
RowSpacing="0"
ColumnSpacing="0"
Margin="0,0,0,10"
VerticalOptions="EndAndExpand">
<Grid.RowDefinitions>
<RowDefinition
Height="10" />
<RowDefinition
Height="Auto" />
<RowDefinition
Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="120" />
<ColumnDefinition
Width="*" />
</Grid.ColumnDefinitions>
<!-- LOGO -->
<Label
Grid.Row="0"
Grid.RowSpan="3"
Margin="20,0"
TextColor="{ DynamicResource InverseTextColor }"
FontSize="74"
FontFamily="{StaticResource FontAwesomeSolid}"
Text="{ x:Static local:FontawesomeSolidFont.Qrcode }"
Style="{ StaticResource FontIcon }"
HorizontalOptions="Start"
VerticalTextAlignment="Center" />
<!-- WELCOME -->
<Label
Grid.Row="1"
Grid.Column="1"
Text="CEU Checkin"
FontSize="22"
TextColor="{ DynamicResource InverseTextColor }"
Style="{ StaticResource LabelBoldStyle }"
VerticalOptions="End"
HorizontalOptions="Start" />
<!-- SUB -->
<Label
Grid.Row="2"
Grid.Column="1"
Text="Scan QR Code to check in/out of your event"
FontSize="16"
TextColor="{ DynamicResource InverseTextColor }"
VerticalOptions="Start"
HorizontalOptions="Start" />
</Grid>
<Grid
Grid.Row="1"
BackgroundColor="{ DynamicResource MainWrapperBackgroundColor }"
grial:Effects.ApplyIOSSafeAreaAsPadding="Bottom" x:Name="ParentGrid">
<!-- TAB -->
<StackLayout x:Name="LoadingIndicator" Grid.Row="0" VerticalOptions="CenterAndExpand">
<local:CustomActivityIndicator
Grid.Row="0"
x:Name="Indicator"
HorizontalOptions="Center"
VerticalOptions="Start" />
<Label
Grid.Row="1"
FontSize="Large"
HorizontalTextAlignment="Center"
Text="{ grial:Translate StringLoading }" />
</StackLayout>
<zxing:ZXingScannerView Grid.Row="0" Grid.RowSpan="2" x:Name="_scanView" OnScanResult="Handle_OnScanResult" IsScanning="{Binding IsScanning}"
WidthRequest="200" HeightRequest="200" />
</Grid>
<!-- CLOSE ICON -->
<Label
Style="{StaticResource IconCloseLabelStyle}">
<Label.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnCloseButtonClicked" />
</Label.GestureRecognizers>
</Label>
</Grid>
</ContentPage.Content>
</ContentPage>
MainActivity.cs
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults) {
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
The best way to fix the issue would be to handle the permission part yourself
A generic permission helper:
using System.Threading.Tasks;
using Xamarin.Essentials;
using static Xamarin.Essentials.Permissions;
public static async Task<PermissionStatus> CheckAndRequestPermissionAsync<TPermission>()
where TPermission : BasePermission, new()
{
TPermission permission = new TPermission();
var status = await permission.CheckStatusAsync();
if (status != PermissionStatus.Granted)
{
status = await permission.RequestAsync();
}
return status;
}
Then use it like
var status = await PermissionsHelper.CheckAndRequestPermissionAsync<Permissions.Camera>();
if(status != PermissionStatus.Granted)
{
return;
}

xamarin.forms ImageSource set from code sometimes disappears, doesnt work on iOS at all

I have this xaml class:
<ContentView
xmlns="http://xamarin.com/schemas/2014/forms"
HeightRequest="130"
WidthRequest="90"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="InteriorCircle.Pages.MainMenu.CV_PinStyle">
<ContentView.Content>
<StackLayout BackgroundColor="Transparent">
<Frame
HeightRequest="130"
WidthRequest="90"
VerticalOptions="Start"
HasShadow="False"
HorizontalOptions="Start"
BackgroundColor="#565656"
Padding="0"
CornerRadius="25"
IsClippedToBounds="true">
<StackLayout Padding="5">
<Grid VerticalOptions="Center" Margin="10,10,0,0" HorizontalOptions="Center">
<Image x:Name="img_pic"
Margin="3,0,0,0"
HorizontalOptions="Center"
VerticalOptions="Center">
<Image.Clip>
<EllipseGeometry
Center="27,27"
RadiusX="27"
RadiusY="27"/>
</Image.Clip>
</Image>
<Ellipse Stroke="#60CED3"
StrokeThickness="6"
WidthRequest="60"
HeightRequest="60"
HorizontalOptions="Start" />
</Grid>
<Label
Margin="0,0,0,0"
x:Name="label_title"
TextColor="White"
LineBreakMode="TailTruncation"
FontFamily="JakartaReg"
VerticalOptions="Start"
FontSize="12"
HorizontalOptions="Center"/>
<Label
x:Name="label_price"
TextColor="White"
FontFamily="JakartaBold"
VerticalOptions="Start"
FontSize="10"
HorizontalOptions="Center"/>
</StackLayout>
</Frame>
</StackLayout>
</ContentView.Content>
</ContentView>
I retrieve content from another class (event) and set it to the properties from here:
private async Task SetContent(EventType events)
{
InitializeComponent();
byte[] bt = Converters.StringToByteArray(events.eventPictureThumb);
label_title.Text = events.name;
label_price.Text = Converters.GetDecimalPriceFromCents(events.priceInCents) + " €";
Device.BeginInvokeOnMainThread(() =>
{
var source = Converters.ReturnImageSourceFromString(Converters.ByteArrayToString(bt));
img_pic.Source = source;
});
}
However, this does not work sometimes on Android, on iOS not at all.
When I set an image directly in xaml, it is always displayed. On iOS, when the image comes from code, it is never displayed. On Android, it is displayed most of the times, but fails sometimes. When multiple objects load into the view the old ones lose their images.
I am adding the view like so:
var startPin = BitmapDescriptorFactory.FromView(new CV_PinStyle(currentEvent));
Pin pin = new Pin
{
Label = currentEvent.name,
Tag = currentEvent.tblEventID+Constants.DELIMITER+currentEvent.userID,
Icon = startPin,
Type = PinType.Place,
Position = position
};
gMap?.Pins?.Add(pin);
So I am doing somethign wrong here,
can you help me?

Can I set the size of the Syncfusion SfTreeView to dynamic?

I put the SfTreeView inside an SfExpander, and the TreeView takes up a lot of space under it.[enter image description here][1]
I tried to put in into a grid and set the height to Auto but didn't work.
[1]: https://i.stack.imgur.com/kDP3l.png
<expander:SfExpander DynamicSizeMode="Content" IsExpanded="False">
<expander:SfExpander.Header>
<Label TextColor="#495F6E" Text="TreeView list" FontSize="16"
</expander:SfExpander.Header>
<expander:SfExpander.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<treeview:SfTreeView x:Name="treeView2"
ItemHeight="34"
ItemsSource="{Binding ImageNodeInfo}">
<treeview:SfTreeView.ItemTemplate>
<DataTemplate>
<Grid x:Name="grid" Padding="2,2,2,2" RowSpacing="0" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1"/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Level, Converter={StaticResource IndentationConverter}}" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="60" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="1" Source="{Binding IsExpanded,Converter={StaticResource ExpanderIconConverter}}"
IsVisible="{Binding HasChildNodes,Converter={StaticResource ExpanderIconVisibilityConverter}}"
VerticalOptions="Center"
HorizontalOptions="Center"
HeightRequest="15"
WidthRequest="15"/>
<Image Grid.Column="2" Source="{Binding Content.ImageIcon}" VerticalOptions="Center" HorizontalOptions="Start" HeightRequest="16" WidthRequest="60"/>
<Grid Grid.Column="3" RowSpacing="1" Padding="1,0,0,0" VerticalOptions="Center">
<Label LineBreakMode="NoWrap" Text="{Binding Content.ItemName}" VerticalTextAlignment="Center" FontSize="Body" FontAttributes="Bold"/>
</Grid>
</Grid>
<BoxView HeightRequest="1" BackgroundColor="Gray" Grid.Row="1"/>
</Grid>
</DataTemplate>
</treeview:SfTreeView.ItemTemplate>
</treeview:SfTreeView>
</Grid>
</expander:SfExpander.Content>
</expander:SfExpander>
We have checked the reported query “How to set the dynamic height” from our end. We would like to inform you that TreeView will be loaded with the view size. If you want to customize the height of TreeView, you can set HeightRequest for TreeView based on the item size. Please refer the following code snippet to achieve your requirement,
Xaml: Use EventToCommand behavior for SfTreeView use command for QueryNodeSize event. Bind HeightRequest of TreeView to update the treeview height based on nodes.
<syncfusion:SfTreeView x:Name="treeView"
ItemHeight="40"
HeightRequest="{Binding TreeViewHeight}"
ChildPropertyName="SubFiles"
ItemTemplateContextType="Node"
AutoExpandMode="AllNodesExpanded"
ItemsSource="{Binding ImageNodeInfo}"
BackgroundColor="Beige">
<syncfusion:SfTreeView.Behaviors>
<local:EventToCommandBehavior EventName="QueryNodeSize" Command="{Binding Path=BindingContext.QueryNodeSizeCommand, Source={x:Reference treeView}}"/>
</syncfusion:SfTreeView.Behaviors>
…
</syncfusion:SfTreeView>
ViewModel: Create Command with QueryNodeSizeEventArgs.
private double treeViewHeight = -1;
//Property to set TreeView height.
public double TreeViewHeight
{
get { return treeViewHeight; }
set
{
treeViewHeight = value;
this.RaisedOnPropertyChanged("TreeViewHeight");
}
}
//Command for QueryNodeSize event.
public Command<QueryNodeSizeEventArgs> QueryNodeSizeCommand { get; set; }
public FileManagerViewModel()
{
//Initialize the command.
QueryNodeSizeCommand = new Command<QueryNodeSizeEventArgs>(QueryNodeSizeMethod);
}
/// <summary>
/// Command method to calculate the TreeView height.
/// </summary>
/// <param name="args">Argument which holds the information of the node.</param>
private void QueryNodeSizeMethod(QueryNodeSizeEventArgs args)
{
var item = args.Node.Content as FileManager;
if (!item.IsHandled)
{
this.TreeViewHeight += args.Height;
item.IsHandled = true;
}
}
We have attached the workable sample based on your requirement. You can find them from the following link,
Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/TreeViewXamarin-1814245514
Regards,
SaiGanesh Sakthivel

Xamarin: Does a Collection.Remove in List remove the wrong object?

I have the strange behaviour in the list view in user's devices which I can't find the same issue on our devices in android written in Xamarin form.
I have a list view which bound with a IList objects in the list collection. Each items inside list view have a command which once clicked the item will be removed from the list.
To remove the item inside the collection, I used Collection.Remove(model). The Collection is a list which stored all ViewModel shown inside the list view and the model are the viewModel got from the Collection.
public ICommand OnAcceptCommand
{
get
{
return new Command(async (param) =>
{
await App.GlobalLayout.PreventMultiClicking(null, async () =>
{
var model = param as HeadCountLineViewModel;
var result = await model.ToggleAccounted(true);
if (result)
Collection.Remove(model);
});
});
}
}
The param is the model from the Collection passed by the item inside the list view.
<DataTemplate x:Key="phoneTemplate">
<ViewCell>
<Frame HasShadow="false" Padding="{StaticResource cellPadding}">
<local:ExtendedFrame Style="{StaticResource cardStyle}" BackgroundColor="{Binding HeadCountLineStatus, Converter={StaticResource accountedToColorConverter}}">
<Grid VerticalOptions="Fill" HorizontalOptions="Fill" RowSpacing="5">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="2*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<controls:CircleImage
Grid.Row="0"
Grid.Column="0"
Margin="0"
Style="{StaticResource profileImageStyle}"
Source="{Binding Source}"
VerticalOptions="Center"
HorizontalOptions="Start">
</controls:CircleImage>
<Label
Grid.Row="0"
Grid.Column="1"
x:Name="childName"
Text="{Binding ChildName}"
Style="{StaticResource MediumBoldFont}"
HorizontalOptions="StartAndExpand"
VerticalOptions="Center">
</Label>
<Image
Grid.Row="0"
Grid.Column="1"
Style="{StaticResource listviewButtonStyle}"
IsVisible="{Binding IsUnAccounted, Converter={StaticResource invertConverter}}"
Source="ic_action_undo.png"
HorizontalOptions="End">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="OnUndoTapped" />
</Image.GestureRecognizers>
</Image>
<Image
Grid.Row="0"
Grid.Column="2"
IsVisible="{Binding IsUnAccounted}"
Style="{StaticResource listviewButtonStyle}"
Source="ic_action_yes.png"
VerticalOptions="FillAndExpand"
HorizontalOptions="End">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnAcceptedTapped">
</TapGestureRecognizer>
</Image.GestureRecognizers>
<Image.Margin>
<OnIdiom x:TypeArguments="Thickness">
<OnIdiom.Phone>0, 0, 5, 0</OnIdiom.Phone>
<OnIdiom.Tablet>5, 5, 20, 5</OnIdiom.Tablet>
</OnIdiom>
</Image.Margin>
</Image>
<Image
Grid.Row="0"
Grid.Column="3"
IsVisible="{Binding IsUnAccounted}"
Style="{StaticResource listviewButtonStyle}"
Source="ic_action_no.png"
VerticalOptions="FillAndExpand"
HorizontalOptions="End">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnAbsentTapped">
</TapGestureRecognizer>
</Image.GestureRecognizers>
<Image.Margin>
<OnIdiom x:TypeArguments="Thickness">
<OnIdiom.Phone>5, 0, 0, 0</OnIdiom.Phone>
<OnIdiom.Tablet>20, 5, 5, 5</OnIdiom.Tablet>
</OnIdiom>
</Image.Margin>
</Image>
<StackLayout Orientation="Horizontal"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="4">
<local:ChildInfoIconsView
ShowClassroom="false"
Child="{Binding Child}"
VerticalOptions="Center">
</local:ChildInfoIconsView>
<ffimageloading:CachedImage
LoadingDelay="2000"
WidthRequest="24"
HeightRequest="24"
x:Name="ImageClassroom"
Source="ic_location"
IsVisible="{Binding HasClass}">
</ffimageloading:CachedImage>
<Label
Style="{StaticResource NormalFont}"
Text="{Binding Class}"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Start"
IsVisible="{Binding HasClass}">
</Label>
<Label
x:Name="note"
Text="{Binding Note, StringFormat='Absent Note : {0}'}"
Style="{StaticResource SmallFont}"
HorizontalOptions="StartAndExpand"
IsVisible="{Binding IsNoteVisible}">
</Label>
</StackLayout>
</Grid>
</local:ExtendedFrame>
</Frame>
</ViewCell>
</DataTemplate>
In the page:
void OnAcceptedTapped (object sender, System.EventArgs e)
{
if (sender is Image && ((Image)sender).BindingContext is HeadCountLineViewModel)
{
var model = ((Image)sender).BindingContext as HeadCountLineViewModel;
var vModel = BindingContext as ShowAllHeadCountLinesViewModel;
vModel.OnAcceptCommand.Execute(model);
}
}
From the first code, I have a Collection.Remove. By any chance wrong model got removed. Visually from user's video, the removed cell looks like it get removed but leaving the Child's name in the removed cell unchanged where other visual element updated e.g. Source.

Categories

Resources