Stumped on Xamarin databinding cast exception - xaml

I've followed examples and worked with XAML for WPF and this never happens so I'm totally confused about why Xamarin Forms is complaining.
Here's a simple form where I'm trying to use a ListView. The general structure is what was generated by Visual Studio but I've put in the ListView with an template for drawing two Labels:
<?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="PrivateDiary.Views.AboutPage"
xmlns:vm="clr-namespace:PrivateDiary.ViewModels"
Title="{Binding Title}">
<ContentPage.BindingContext>
<vm:AboutViewModel />
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<Color x:Key="Accent">#96d1ff</Color>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout Orientation="Vertical">
<ListView x:Name="AboutListView"
ItemsSource="{Binding Items}"
SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<Grid VerticalOptions="Center" HorizontalOptions="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}" Grid.Column="0" />
<Label Text="{Binding Detail}" Grid.Column="1" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
The code behind:
namespace PrivateDiary.Views
{
using Xamarin.Forms;
public partial class AboutPage : ContentPage
{
public AboutPage()
{
InitializeComponent();
}
}
}
and my View Model:
namespace PrivateDiary.ViewModels
{
using System.Collections.ObjectModel;
public class AboutViewModel : BaseViewModel
{
public ObservableCollection<AboutItem> Items { get; set; } = new ObservableCollection<AboutItem>();
public AboutViewModel()
{
Title = "About";
Items.Add(new AboutItem {Name = "Version", Detail = "0.3"});
Items.Add(new AboutItem {Name = "Privacy Policy", Detail = "#privacy"});
}
}
public class AboutItem
{
public string Name { get; set; }
public string Detail { get; set; }
}
}
BaseViewModel is the stock one generated by Visual Studio 2019 (16.10.3) so I won't list it here. It implements the details for INotifyPropertyChanged, a page Title property and IsBusy property.
When I run the app I get this:
If I removed the Items.Add(...) lines there's no problems.
Any ideas why it fails to cast?

Please add element ViewCell outside of element Grid in your xaml
You can refer to the following code:
<ContentPage.BindingContext>
<listviewapp1:AboutViewModel></listviewapp1:AboutViewModel>
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout Orientation="Vertical">
<ListView x:Name="AboutListView"
ItemsSource="{Binding Items}"
SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<!--add ViewCell here-->
<ViewCell>
<Grid VerticalOptions="Center" HorizontalOptions="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}" Grid.Column="0" />
<Label Text="{Binding Detail}" Grid.Column="1" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>

Related

RelativeSource in MAUI control not bound

I'm going through simple example explained in video:
https://youtu.be/5Qga2pniN78?t=961
At 16. minute (timestamp in link above), he implements the Delete Command on SwipeItem.
In my local project, everything worked so far, but Delete Command is never triggered. I checked source generators, DeleteCommand exists.
My XAML:
<?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="MauiApp1.MainPage"
xmlns:viewmodel="clr-namespace:MauiApp1.ViewModel"
x:DataType="viewmodel:MainViewModel">
<Grid RowDefinitions="100, Auto, *"
ColumnDefinitions=".75*, .25*"
Padding="10"
RowSpacing="10"
ColumnSpacing="10">
<Image Grid.ColumnSpan="2" Source="tom.jpg"
BackgroundColor="Transparent"></Image>
<Entry Placeholder="Enter task" Grid.Row="1" Text="{Binding Text}"></Entry>
<Button Text="Add" Grid.Row="1" Grid.Column="1" Command="{Binding AddCommand}"></Button>
<CollectionView Grid.Row="2" Grid.ColumnSpan="2" ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="{x:Type x:String}">
<SwipeView>
<SwipeView.RightItems>
<SwipeItem Text="Delete" BackgroundColor="Red"
Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}}, Path=DeleteCommand}"
CommandParameter="{Binding .}">
</SwipeItem>
</SwipeView.RightItems>
<Grid Padding="0,5">
<Frame>
<Label Text="{Binding .}" FontSize="24"></Label>
</Frame>
</Grid>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</ContentPage>
View Model:
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace MauiApp1.ViewModel
{
public partial class MainViewModel : ObservableObject
{
public MainViewModel()
{
Items = new();
Items.Add("test");
}
[ObservableProperty]
private ObservableCollection<string> items;
[ObservableProperty]
private string text;
[RelayCommand]
private void Add()
{
if (string.IsNullOrWhiteSpace(text))
{
return;
}
Items.Add(Text);
Text = string.Empty;
}
[RelayCommand]
private void Delete(string s)
{
if (Items.Contains(s))
{
Items.Remove(s);
}
}
}
}
Why is DeleteCommand not triggering?
try this
Command="{Binding BindingContext.DeleteCommand,
Source={x:Reference myPage}}"
where myPage is your page's name
<ContentPage x:Name="myPage" ...
Resolved,
I forgot to add <SwipeItems> element after <SwipeView.RightItems>.
AncestorType={x:Type viewmodel:MainViewModel}
Your viewmodel is not part of the visual tree, so you can't bind to it with relative source anyway.
You can use your CollectionView's Binding Context and then the specific property you need:
Command="{Binding BindingContext.DeleteCommand, Source={RelativeSource AncestorType={x:Type CollectionView}}}

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.

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.

Xamarin Forms with UWP Refresh causes value to disappear

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.

Xamarin.Forms: How to diplay a modal when an item in ListView is clicked?

Good Day everyone. I'm currently doing a simple application in Xamarin.Forms that allows me to CRUD record of an Employee. The created records are displayed on a ListView. Here's my screenshot.
What I want to do is whenever I click an Item on the ListView, is it will display a modal with a more detailed information of an Employee e.g (Birthday, Address, Gender, Work Experience). How can I do that? Is that even possible? Can you show me how?
This is my code that displays the ListView.
<?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="XamarinFormsDemo.EmployeeRecordsPage"
xmlns:ViewModels="clr-namespace:XamarinFormsDemo.ViewModels;assembly=XamarinFormsDemo"
xmlns:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin.Abstractions"
BackgroundImage="bg3.jpg"
Title="List of Employees">
<ContentPage.BindingContext>
<ViewModels:MainViewModel/>
</ContentPage.BindingContext>
<StackLayout Orientation="Vertical">
<ListView ItemsSource="{Binding EmployeesList, Mode=TwoWay}"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="10" RowSpacing="10" ColumnSpacing="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<controls:CircleImage Source="icon.png"
HeightRequest="66"
HorizontalOptions="CenterAndExpand"
Aspect="AspectFill"
WidthRequest="66"
Grid.RowSpan="2"
/>
<Label Grid.Column="1"
Text="{Binding Name}"
TextColor="#24e97d"
FontSize="24"/>
<Label Grid.Column="1"
Grid.Row="1"
Text="{Binding Department}"
TextColor="White"
FontSize="18"
Opacity="0.6"/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackLayout Orientation="Vertical"
Padding="30,10,30,10"
HeightRequest="20"
BackgroundColor="#24e97d"
VerticalOptions="Center"
Opacity="0.5">
<Label Text="© Copyright 2015 smesoft.com.ph All Rights Reserved "
HorizontalTextAlignment="Center"
VerticalOptions="Center"
HorizontalOptions="Center" />
</StackLayout>
</StackLayout>
</ContentPage>
NOTE: Records that are displayed are CREATED in ASP.NET Web Application and just displayed on a ListView in UWP. If you need to see more codes, just please let me know.
Thanks a lot Guys.
To bind a command to item selected property see the example bellow otherwise ItemSelected will bind to a model property only
For full example see https://github.com/TheRealAdamKemp/Xamarin.Forms-Tests/blob/master/RssTest/View/Pages/MainPage.xaml.cs
Now you can bind an Icommand which could have something like
private Command login;
public ICommand Login
{
get
{
login = login ?? new Command(DoLogin);
return login;
}
}
private async void DoLogin()
{
await Navigation.PopModalAsync(new MySampXamlPage());
//await DisplayAlert("Hai", "thats r8", "ok");
}
and view :
[Navigation.RegisterViewModel(typeof(RssTest.ViewModel.Pages.MainPageViewModel))]
public partial class MainPage : ContentPage
{
public const string ItemSelectedCommandPropertyName = "ItemSelectedCommand";
public static BindableProperty ItemSelectedCommandProperty = BindableProperty.Create(
propertyName: "ItemSelectedCommand",
returnType: typeof(ICommand),
declaringType: typeof(MainPage),
defaultValue: null);
public ICommand ItemSelectedCommand
{
get { return (ICommand)GetValue(ItemSelectedCommandProperty); }
set { SetValue(ItemSelectedCommandProperty, value); }
}
public MainPage ()
{
InitializeComponent();
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
RemoveBinding(ItemSelectedCommandProperty);
SetBinding(ItemSelectedCommandProperty, new Binding(ItemSelectedCommandPropertyName));
}
protected override void OnAppearing()
{
base.OnAppearing();
_listView.SelectedItem = null;
}
private void HandleItemSelected(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem == null)
{
return;
}
var command = ItemSelectedCommand;
if (command != null && command.CanExecute(e.SelectedItem))
{
command.Execute(e.SelectedItem);
}
}
}
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:ValueConverters="clr-namespace:RssTest.ValueConverters;assembly=RssTest"
x:Class="RssTest.View.Pages.MainPage"
Title="{Binding Title}">
<ContentPage.Resources>
<ResourceDictionary>
<ValueConverters:BooleanNegationConverter x:Key="not" />
</ResourceDictionary>
</ContentPage.Resources>
<Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<ListView x:Name="_listView"
IsVisible="{Binding IsLoading, Converter={StaticResource not}" ItemsSource="{Binding Items}"
ItemSelected="HandleItemSelected"
VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Title}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ActivityIndicator IsVisible="{Binding IsLoading}" IsRunning="{Binding IsLoading}"
VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" />
</Grid>
</ContentPage>