Xamarin Forms with UWP Refresh causes value to disappear - xaml

I have a Xamarin Forms application using Android and UWP. Everything works fine under Android but under UWP I have a problem when I want to modify some values displayed on the screen.
Here is my (simplified) ViewModel (using Fody.PropertyChanged) :
public class SalesViewModel : BaseAppViewModel
{
public ObservableCollection<SaleModel> Sales { get; set; }
= new ObservableCollection<SaleModel>();
[DoNotNotify]
public ICommand AddQuantityCommand => new Command<SaleModel>(item =>
{
item.Quantity += 1;
});
}
The BaseAppViewModel implement the INotifyPropertyChanged interface for Fody.PropertyChanged
The (simplified) SaleModel class:
public class SaleModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public double Quantity { get; set; }
}
And the (part of the) XAML which display the list of SaleModel's
<ListView x:Name="ListView" ItemsSource="{Binding Sales, Mode=TwoWay}" SelectedItem="{Binding SelectedSale, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="arrow.png">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.AddQuantityCommand, Source={x:Reference Name=SalesPage}}" CommandParameter="{Binding .}" />
</Image.GestureRecognizers>
</Image>
<Label Grid.Column="1" Text="{Binding Quantity, Mode=OneWay}"
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
When clicking on the Image, the quantity is incremented but the value disappear from the screen under UWP.

I have tested your code and reproduced your issue. And I written the following ViewCell replace yours. Please try to modify your ViewCell.
<ViewCell>
<StackLayout BackgroundColor="#eee"
Orientation="Vertical">
<StackLayout Orientation="Horizontal">
<Image Source="time.jpg" HeightRequest="50" WidthRequest="50" >
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding AddQuantityCommand} " CommandParameter="{Binding .}"/>
</Image.GestureRecognizers>
</Image>
<Label Text="{Binding Quantity}"
TextColor="#f35e20" />
<Label Text="{Binding Quantity}"
HorizontalOptions="EndAndExpand"
TextColor="#503026" />
</StackLayout>
</StackLayout>
</ViewCell>
I have upload code sample to github. Please refer to.

Related

Xamarin forms, find corresponding checkbox to label in listview and check it when clicked on label

I have this ListView:
<ListView x:Name="listview_items"
Margin="0,10,0,0"
VerticalScrollBarVisibility="Always"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="5"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding itemText}"
FontSize="22"
Margin="0,5,0,5"
FontFamily="Font_11"
TextColor="#424242">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</Label.GestureRecognizers>
</Label>
<CheckBox
Color="#97A5AD"
IsChecked="{Binding isChecked}"
CheckedChanged="chk_accept_shipment_CheckedChanged"
Grid.Column="1"
Scale="1"
HorizontalOptions="End"
Margin="0,0,0,0"
x:Uid="{Binding itemID}"
x:Name="{Binding itemID}"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
As you can see, it contains a Label and a CheckBox, when the user checks the checkbox, I gets checked. But now, I have a gesture recognizer attached to the label. When the user taps the label, I want to find out which checkbox is next to the label and also check it (as if the user actually clicked the checkbox).
How do I find the corresponding checkbox to the label next to it?
I would personally bind the IsChecked property to my ViewModel.
Example:
<StackLayout
HorizontalOptions="Start"
Orientation="Horizontal">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding SelectAllCategoriesCommand}" NumberOfTapsRequired="1" />
</StackLayout.GestureRecognizers>
<CheckBox IsChecked="{Binding IsAllCategoriesSelected}" />
<Label Text="Select All Categories" />
</StackLayout>
The binded property can be something like :
private bool _isAllCategoriesSelected;
public bool IsAllCategoriesSelected
{
get => _isAllCategoriesSelected;
set
{
_isAllCategoriesSelected = value;
RaisePropertyChanged(() => IsAllCategoriesSelected);
}
}
First you have to pass CommandParameter in tap so you can get that in TapGestureRecognizer_Tapped In that you will get which Item table click so according that you have to check check box
<Label.GestureRecognizers>
<TapGestureRecognizer CommandParameter="{Binding itemID}" Tapped="TapGestureRecognizer_Tapped"/>
</Label.GestureRecognizers>
async void TapGestureRecognizer_Tapped(System.Object sender, System.EventArgs e)
{
var d = (TappedEventArgs)e;
var data = d.Parameter as int;//yor itemID type
}

Xamarin's Buttons issue

I've only recently started Xamarin and I'm having trouble figuring out how to design a few blocks. I'm trying to create some simple buttons to navigate with and it was decent (picture 2). But as soon as I tried binding it to a data, the design basically ran off (picture 1). Any suggestions?
Image of the problem
Image of the attempt
Below are the codes for picture 1:
<ListView x:Name="displayCourses" ItemsSource="{Binding CourseName}">
<ListView.Header>
<Grid HorizontalOptions="Center">
<!--<Button Text="{Binding CourseName}" BackgroundColor="#ea3e15"
CornerRadius="20" WidthRequest="290" HeightRequest="130"
FontAttributes="Bold" FontSize="26" Clicked="NextPage"
/>-->
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Button Text="{Binding CourseName}" BackgroundColor="#ea3e15" TextColor="#fff"
CornerRadius="20"
FontAttributes="Bold" FontSize="26"
/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
CS codes linking the data together
protected async override void OnAppearing()
{
base.OnAppearing();
displayCourses.ItemsSource = await firebaseHelper.GetCourses();
}
public async Task<List<Course>> GetCourses()
{
FirebaseClient firebase = new FirebaseClient("https://pra-ece32-default-rtdb.firebaseio.com/");
return (await firebase
.Child("Courses")
.OnceAsync<Course>()).Select(item => new Course
{
CourseName = item.Object.CourseName,
CourseID = item.Object.CourseID,
ExamDate = item.Object.ExamDate,
}).ToList();
}
The width of a row inside the listview will always take up the entire width of the listview itself. There is no way to have extra space between the end of a Row and the edge of the listview, nor would that make any sense.
But you can use Grid to meet your requirement. Please set ListView HasUnevenRow="True" to automatically size row height to fit content.
<ListView
x:Name="displayCourses"
HasUnevenRows="True"
ItemsSource="{Binding courses}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button
Grid.Column="1"
Margin="20"
BackgroundColor="#ea3e15"
CornerRadius="20"
FontAttributes="Bold"
FontSize="26"
HeightRequest="50"
Text="{Binding coursename}"
TextColor="#fff"
WidthRequest="200" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Define listview in resource file which can be used in different places with same model

I have created the following ListView to display data
<dataControls:RadListView x:Name="ItemsListView"
ItemsSource="{Binding StudyResults,Mode=TwoWay}"
MinimumHeightRequest="70"
HeightRequest="{Binding Height}"
SelectedItem="{Binding SelectedItem,Mode=TwoWay}">
<dataControls:RadListView.ItemTemplate>
<DataTemplate>
<listView:ListViewTemplateCell>
<listView:ListViewTemplateCell.View>
<Grid Padding="2,2,2,5" HorizontalOptions="FillAndExpand">
<StackLayout Padding="5,1,1,5" Grid.Column="0">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<maxline:XfMaxLinesLabel MaxLines="2" Text="{Binding BriefTitle, Mode=TwoWay}" Style="{StaticResource ListViewLabelStyle}" TextColor="Black"/>
</Grid>
<StackLayout Padding="0,0,0,0" HorizontalOptions="Fill">
<BoxView Margin="0"
BackgroundColor="Gray"
HeightRequest=".25" />
<Label Text="{Binding ClosestFacility.Name, Mode=TwoWay}" Style="{StaticResource ListViewLabelStyle}"/>
<BoxView Margin="0"
BackgroundColor="Gray"
HeightRequest=".25" />
</StackLayout>
</StackLayout>
</Grid>
</listView:ListViewTemplateCell.View>
</listView:ListViewTemplateCell>
</DataTemplate>
</dataControls:RadListView.ItemTemplate>
</dataControls:RadListView>
I want to reuse this exact same ListView + markup in a other screens/view, just with a different ItemsSource it will be bound to same model. I need to use different item source in different screens.
Is there a better way to create some type of resource so I can reuse this?
As lvan's opinion, you can set DataTemplate in ContentPage.Resource or ResourceDictionary, Some code like this:
<ContentPage.Resources>
<DataTemplate x:Key="Radtemplate">
<listView:ListViewTemplateCell>
<listView:ListViewTemplateCell.View>
<Grid Padding="2,2,2,5" HorizontalOptions="FillAndExpand">
<StackLayout Padding="5,1,1,5" Grid.Column="0">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<maxline:XfMaxLinesLabel MaxLines="2" Text="{Binding BriefTitle, Mode=TwoWay}" Style="{StaticResource ListViewLabelStyle}" TextColor="Black"/>
</Grid>
<StackLayout Padding="0,0,0,0" HorizontalOptions="Fill">
<BoxView Margin="0"
BackgroundColor="Gray"
HeightRequest=".25" />
<Label Text="{Binding ClosestFacility.Name, Mode=TwoWay}" Style="{StaticResource ListViewLabelStyle}"/>
<BoxView Margin="0"
BackgroundColor="Gray"
HeightRequest=".25" />
</StackLayout>
</StackLayout>
</Grid>
</listView:ListViewTemplateCell.View>
</listView:ListViewTemplateCell>
</DataTemplate>
</ContentPage.Resources>
<StackLayout>
<!-- Place new controls here -->
<dataControls:RadListView x:Name="ItemsListView" ItemTemplate="{StaticResource Radtemplate}"
ItemsSource="{Binding StudyResults,Mode=TwoWay}"
MinimumHeightRequest="70"
HeightRequest="{Binding Height}"
SelectedItem="{Binding SelectedItem,Mode=TwoWay}">
</dataControls:RadListView>
</StackLayout>
About DateTemplate detailed info, you can take a look the following article:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/templates/data-templates/creating
Update:
Because RadListView is the third party control, I can not install it, so I use ListView as an example, it is the same, you can take a look how to use TapGestureRecognizer.
Please give the Page an x:name=listviewpage firstly, then
<ContentPage
x:Class="demo3.listviewsample.Page2"
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"
x:Name="listviewpage"
mc:Ignorable="d">
<ContentPage.Resources>
<DataTemplate x:Key="datatemplate1">
<ViewCell>
<StackLayout Margin="5" VerticalOptions="FillAndExpand">
<BoxView BackgroundColor="AliceBlue" HeightRequest="30" />
<Label Text="{Binding username}">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding BindingContext.command, Source={x:Reference listviewpage}}" CommandParameter="{Binding Email}" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<ListView
HasUnevenRows="True"
ItemTemplate="{StaticResource datatemplate1}"
ItemsSource="{Binding models}" />
</StackLayout>
</ContentPage.Content>
Or you can give ViewCell an x:Name viewcell1 firstly, then:
<ContentPage.Resources>
<DataTemplate x:Key="datatemplate1">
<ViewCell x:Name="viewcell">
<StackLayout Margin="5" VerticalOptions="FillAndExpand">
<BoxView BackgroundColor="AliceBlue" HeightRequest="30" />
<Label Text="{Binding username}">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Parent.BindingContext.command, Source={x:Reference viewcell}}" CommandParameter="{Binding Email}" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ContentPage.Resources>
public partial class Page2 : ContentPage
{
public ObservableCollection<model3> models { get; set; }
public RelayCommand1 command { get; set; }
public Page2()
{
InitializeComponent();
models = new ObservableCollection<model3>()
{
new model3(){username="cherry",Email="cherry#outlook.com"},
new model3(){username="barry",Email="barry#outlook.com"}
};
command = new RelayCommand1(obj => method1((string)obj));
this.BindingContext = this;
}
private void method1(string str)
{
Console.WriteLine("the email is {0}",str);
}
}
public class model3
{
public string username { get; set; }
public string Email { get; set; }
}
Here is the Command that inherit ICommand:
public class RelayCommand1 : ICommand
{
private readonly Predicate<object> _canExecute;
private readonly Action<object> _execute;
public RelayCommand1(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand1(Action<object> execute, Predicate<object> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_execute(parameter);
}
}
When I tap label, it works fine.
You can set DataTemplate as resource, that would work.

How bind a command in DataTemplate in Resource Dictionary?

I'm trying to make a better solution architecture, for that I've separated many parts of code in differents files. Because my application use a lot of DataTemplates, I push them in different ResourceDictionary.xaml files.
Problem :
I have a view Agenda.xaml, with the viewModel AgendaViewModel. This view have a ListView which call's datatemplate in external ResourceDictionary file. But if I want put a Binding Command in the dataTemplate, the command is never executed because (I guess) the resource Dictionary where is my DataTemplate not reference ViewModel.
What can I do ?
I've already tried some weird Binding code like
<TapGestureRecognizer Command="{Binding BindingContext.OpenActiviteCommand, Source={x:Reference agendaPage}}" CommandParameter="{Binding .}"/>
Where "agendaPage" is the x:Name of Agenda.xaml.
All I found on Google was about WPF and Binding property not available on Xamarin Forms (RelativeSource, ElementName etc...)
I know I can put dataTemplate in my Agenda.xaml view, but I really want keep it in an external file. I want avoid view files with 1500 lines....
This is my Agenda.xaml view
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Corim.Portable.CorimTouch.ViewForms.Agenda.AgendaViewDetail"
xmlns:converters="clr-namespace:Corim.Portable.CorimTouch.Converters"
Title="Agenda"
x:Name="agendaPage">
<ContentPage.Content>
<Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="{StaticResource LightGrayCorim}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Liste itv,pointage,activite -->
<ListView
x:Name="listAgenda"
Grid.Row="1"
SeparatorVisibility="None"
HasUnevenRows="True"
SelectionMode="None"
CachingStrategy="RecycleElement"
ItemsSource="{Binding AgendaList}"
ItemTemplate="{StaticResource agendaTemplateSelector}"
BackgroundColor="{StaticResource LightGrayCorim}">
</ListView>
</Grid>
</ContentPage.Content>
</ContentPage>
And this is one part of Datatemplate in AgendaTemplates.xaml
<DataTemplate x:Key="agenda-adresse-intervention">
<ViewCell>
<Frame Margin="10,5,10,0" HasShadow="False" Padding="0" CornerRadius="10" IsClippedToBounds="True">
<controls:CustomTappedStackLayout
BackgroundColor="White"
TappedBackgroundColor="{StaticResource RollOver}"
HorizontalOptions="FillAndExpand"
Orientation="Horizontal"
Padding="10">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.OpenParcCommand, Source={x:Reference agendaPage}}" CommandParameter="{Binding .}" NumberOfTapsRequired="1"/>
</StackLayout.GestureRecognizers>
<Image
Source="localisation_adresse"
WidthRequest="30"
HeightRequest="30"
Aspect="AspectFit"
HorizontalOptions="Start"
Margin="10"
VerticalOptions="StartAndExpand"/>
<StackLayout
HorizontalOptions="FillAndExpand"
Orientation="Vertical">
<Label
Text="{Binding Client}"
IsVisible="{Binding Client, Converter={StaticResource StringEmptyBooleanConverter}}"
FontFamily="{StaticResource SemiBoldFont}"
FontSize="{StaticResource MediumTextSize}"
TextColor="Black"/>
<Label
Text="{Binding Title}"
IsVisible="{Binding Title, Converter={StaticResource StringEmptyBooleanConverter}}"
FontFamily="{StaticResource RegularFont}"
FontSize="{StaticResource DefaultTextSize}"
TextColor="Gray"/>
</StackLayout>
</controls:CustomTappedStackLayout>
</Frame>
</ViewCell>
</DataTemplate>
But if I want put a Binding Command in the dataTemplate, the command
is never executed because (I guess) the resource Dictionary where is
my DataTemplate not reference ViewModel.
You guess wrong: it's totally fine to do what you are doing and should work transparently. The binding is resolved at runtime your data template does not know anything about the object that will be bound.
1st: drop the BindingContext.OpenActiviteCommand nonsense :) Just bind to OpenActiviteCommand, the only question is:
2nd: Where is your OpenActiviteCommand ?
The data context of your AgendaTemplates is the item in your AgendaList.
If the type of the AgendaList is an ObservableCollection<AgendaViewModel>, and your AgendaViewModel has a OpenParcCommand then it should be fine:
public class AgendaViewModel
{
public AgendaViewModel(ICommand openParcCommand)
{
OpenParcCommand = openParcCommand;
}
public ICommand OpenParcCommand { get; }
}
and in your AgendaPageViewModel:
public class AgendaPageViewModel
{
public ObservableCollection<AgendaViewModel> AgendaList { get; }
}
Thanks to #Roubachof
The soluce was replace my ListView of InterventionModel by ListView of AgendaDataViewModel.
AgendaViewModel is a new class which contains all the commands I need, and an InterventionModel.
this is AgendaDataViewModel :
public class AgendaDataViewModel : HybridContentViewModel
{
private InterventionModel _model;
public InterventionModel Model
{
get => _model;
set { _model = value; }
}
public ICommand OpenActiviteCommand { get; private set; }
public AgendaDataViewModel()
{
this.OpenActiviteCommand = new Command<InterventionModel>(this.OpenActivite);
}
/// <summary>
/// Ouvre le formulaire d'édition de l'activité
/// </summary>
/// <param name="model"></param>
private void OpenActivite(InterventionModel model)
{
//TODO amener sur le formulaire d'activité
}
}
my AgendaTemplate.xaml
<!--Template pour l'affichage du parc-->
<DataTemplate x:Key="agenda-adresse-intervention">
<ViewCell>
<Frame Margin="10,5,10,0" HasShadow="False" Padding="0" CornerRadius="10" IsClippedToBounds="True">
<controls:CustomTappedStackLayout
BackgroundColor="White"
TappedBackgroundColor="{StaticResource RollOver}"
HorizontalOptions="FillAndExpand"
Orientation="Horizontal"
Padding="10">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OpenParcCommand}" CommandParameter="{Binding Model}" NumberOfTapsRequired="1"/>
</StackLayout.GestureRecognizers>
<Image
Source="localisation_adresse"
WidthRequest="30"
HeightRequest="30"
Aspect="AspectFit"
HorizontalOptions="Start"
Margin="10"
VerticalOptions="StartAndExpand"/>
<StackLayout
HorizontalOptions="FillAndExpand"
Orientation="Vertical">
<Label
Text="{Binding Model.Client}"
IsVisible="{Binding Model.Client, Converter={StaticResource StringEmptyBooleanConverter}}"
FontFamily="{StaticResource SemiBoldFont}"
FontSize="{StaticResource MediumTextSize}"
TextColor="Black"/>
<Label
Text="{Binding Model.Title}"
IsVisible="{Binding Model.Title, Converter={StaticResource StringEmptyBooleanConverter}}"
FontFamily="{StaticResource RegularFont}"
FontSize="{StaticResource DefaultTextSize}"
TextColor="Gray"/>
</StackLayout>
</controls:CustomTappedStackLayout>
</Frame>
</ViewCell>
</DataTemplate>
As you can see, the values binding is made by this line :
{Binding Model.Client}
where Client is the name of Binded property. And to Bind a Command, you don't need Model, and just bind like this :
Command={Binding CommandName}
Hope it helps someone in the future !

Xamarin Forms Carousel view issue with binding

Hello I’m having an issue with binding a list of string to my Carousel View
First I have a list of an object I get from my server
public class PostObject
{
public string PostOwner { get; set; }
public string Id { get; set; }
public string Post { get; set; }
public string ProfileImage { get; set; }
public List<string> PostImages { get; set; }
}
List<PostObject> posts = new List<PostObject>();
This works as I expected.
Next I have a card view I created and within the card view I want to have a Carousel View.
So I have setup my Xaml like this (omitting the parts that works for clarity)
<?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:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin"
NavigationPage.HasNavigationBar="True"
NavigationPage.HasBackButton="False"
NavigationPage.BackButtonTitle="Back"
Title="amici"
x:Class="amici.Posts">
<NavigationPage.TitleView>
<StackLayout Orientation="Horizontal" VerticalOptions="Center" Spacing="10" >
<Label x:Name="GroupTitle" TextColor="White" FontSize="Medium"/>
</StackLayout>
</NavigationPage.TitleView>
<ContentPage.ToolbarItems>
<ToolbarItem Name="iconexample" Icon="settings.png" Priority="0" Order="Primary" />
</ContentPage.ToolbarItems>
<ContentPage.Content>
<StackLayout>
<ListView x:Name="ItemsListView"
VerticalOptions="FillAndExpand"
HasUnevenRows="true"
IsPullToRefreshEnabled="true"
IsRefreshing="{Binding IsBusy, Mode=OneWay}"
CachingStrategy="RecycleElement">
<!--ItemSelected="OnItemSelected"-->
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell >
<StackLayout Padding="10">
<Frame x:Name="myframe" HasShadow="True" >
<Grid HorizontalOptions="FillAndExpand" RowSpacing="0" ColumnSpacing="0" >
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="20" />
<RowDefinition Height="20" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Text="{Binding PostOwner}" LineBreakMode="WordWrap" Font="Bold,16" />
<controls:CircleImage Grid.Row="0" Margin="10" BorderColor="white" BorderThickness="1" VerticalOptions="Start" HorizontalOptions="Start" Source="{Binding ProfileImage}" Aspect="AspectFit">
<controls:CircleImage.WidthRequest>
<OnPlatform x:TypeArguments="x:Double">
<On Platform="Android, iOS">65</On>
</OnPlatform>
</controls:CircleImage.WidthRequest>
<controls:CircleImage.HeightRequest>
<OnPlatform x:TypeArguments="x:Double">
<On Platform="Android, iOS">65</On>
</OnPlatform>
</controls:CircleImage.HeightRequest>
</controls:CircleImage>
<Label Grid.Row="1" Text="{Binding Post}" LineBreakMode="WordWrap" Font="Bold,16" />
<CarouselView x:Name="PostImages" Grid.Row="2" ItemsSource="{Binding PostImages}">
<CarouselView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding .}" Aspect="AspectFill" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<!--<Image Grid.Row="2" Source="{Binding ImageURL}" Aspect="AspectFill" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />-->
<BoxView Grid.Row="3" BackgroundColor="black" HeightRequest="1" HorizontalOptions="FillAndExpand"/>
<StackLayout Grid.Row="4" Orientation="Horizontal" >
<Label Text="Likes: " LineBreakMode="NoWrap" Font="Bold,14" />
<Label Text="0" LineBreakMode="NoWrap" FontSize="14" />
</StackLayout>
<StackLayout Grid.Row="5" Orientation="Horizontal" >
<Label Text="Comments: " LineBreakMode="NoWrap" Font="Bold,14" HorizontalOptions="End" />
<Label Text="0" HorizontalOptions="End" LineBreakMode="NoWrap" FontSize="14" />
</StackLayout>
<!--<Label Grid.Row="2" Text="{Binding OwnerFullName}" LineBreakMode="NoWrap" FontSize="16" />-->
</Grid>
</Frame>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
In my code behind I have this
public Posts (GroupInfo ginfo)
{
InitializeComponent ();
GroupTitle.Text = ginfo.Title;
CurrentGroupInfo = ginfo;
GetDataPosts();
ItemsListView.RefreshCommand = new Command(() => {
GetDataPosts();
ItemsListView.IsRefreshing = false;
});
}
public void GetDataPosts()
{
try
{
string apikey = Application.Current.Properties["api"].ToString();
ItemsListView.ItemsSource = null;
posts.Clear();
if (RestController.GetMyPostData(ref posts, CurrentGroupInfo.Id.ToString(), apikey))
{
ItemsListView.ItemsSource = posts;
}
}
catch(Exception e)
{
Debug.WriteLine(e.Message);
}
}
now up to this point everything works and no errors but when the app goes to render the page I get a error
System.TypeInitializationException: The type initializer for 'Xamarin.Forms.ItemsView' threw an exception.
which I trace back to the Carousel View. When I comment out the Carousel View the it works. so I'm thinking I can't bind OR use the Carousel View in the way I thought?
The CarouselView used to be a plugin that has now become part of Xamarin.Forms effective with version 4. You can use an earlier XF version but you will need to get this plugin, add assembly references to your XAML and put initialization code in your platform specific projects.
Alternatively, you could upgrade to Xamarin.Forms 4
Even though you can see the Carousel View on Xamarin.Forms 3.6.0.344457, it only defines an interface there. There're no implementations and properties in the Carousel View Class.
You can only utilize it under Xamarin.Forms 4.0. As it is still a preview version now, there're some limitations. See my post here: https://stackoverflow.com/a/56235795/8354952 for more information.