Binding scope doesn't change inside collectionview/listview - xaml

I have an ObservableCollection of Stylist that I want to display in my view using a CollectionView
this is the code for collectionview
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodels="clr-namespace:Appointments.ViewModels"
x:DataType="viewmodels:WallViewModel"
x:Class="Appointments.Views.WallPage">
<ContentPage.BindingContext>
<viewmodels:WallViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout>
<FlexLayout
JustifyContent="SpaceBetween"
Margin="10, 20">
<Entry
WidthRequest="250"
Placeholder="search.."/>
<Button
Text="Filters"
Command="{Binding OpenFilterCommand}"
/>
</FlexLayout>
<CollectionView
x:Name="StylistList"
BackgroundColor="Transparent"
ItemsSource="{Binding Stylists}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding Name}"/>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
The Stylist model inherits from a User model that has a public property "Name"
public string Name { get; set; }
but if I run this code it will throw an error saying
"Binding: Propery "Name" not found on WallViewModel"
but if I change the that label to bind to
<Label Text="{Binding .}"/>
and while the app is running I change it back to
<Label Text="{Binding Name}"/>
it will work fine and display all the names inside the collection

Due to you set the code below into a User model, when you use x:DataType="viewmodels:WallViewModel" would thrown the error Property "Name" not found on "App8.WallViewModel"..
public string Name { get; set; }
If you change the use the x:DataType, you nned to use the class which include the Name property.
For more details about the x:DataType, please check the MS docs.
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-
binding/compiled-bindings
As Jason said, remove the x:DataType="viewmodels:WallViewModel" would fix the this error.
After removing the x:DataType="viewmodels:WallViewModel, <Label Text="{Binding Name}"/> should work.

Just put the iterated type inside the DataTemplate:
<DataTemplate x:DataType="viewmodels:xxx">
...
</DataTemplate>

Related

Workaround for ScrollView not scrolling inside a StackLayout in Maui

I have a page that presents a list of items in a CollectionView within a ScrollView. I want the user to be able to add a new item to this list by hitting an "add" button or tapping an image at the top of the page. I first tried this using the hierarchy of views shown below. The code below is an abbreviated version of the real thing. I discovered that putting a ScrollView within a VerticalStackLayout breaks the scrolling in Maui! Here is the reported bug.
I tried deleting the VerticalStackLayout that precedes the ScrollView and the scrolling still doesn't work.
<ContentPage.Content>
<VerticalStackLayout>
<VerticalStackLayout HorizontalOptions="Center">
<Image Source="add.png">
<ImageGestureRecongnizers>
<TapGestureRecognizer... Code to add new item to MyCollection...]/>
</ImageGestureRecognizers>
</Image>
</VerticalStackLayout>
<ScrollView>
<CollectionView ItemsSource="{Binding MyCollection}">
<CollectionView.ItemTemplate>
<DataTemplate>
[Layout for displaying items in MyCollection...]
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ScrollView>
<VerticalStackLayout
</ContentPage.Content>
I'd greatly appreciate suggestions on a workaround to allow the viewing of the scrollable list and adding an item to the list by tapping an object (button or image) that's always visible on the page regardless of how the list is scrolled.
Actually for the Xaml, this will work...
<?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="MauiAppTest01.MainPage">
<Grid RowDefinitions="30,*">
<CollectionView ItemsSource="{Binding MyCollection}"
Grid.Row="1">
<CollectionView.ItemTemplate>
<DataTemplate>
<VerticalStackLayout >
<Label Text="{Binding Name}" FontSize="Large" />
</VerticalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Image Source="dotnet_bot.png" HeightRequest="100" WidthRequest="100"
Margin="0,0,50,20">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</Image.GestureRecognizers>
</Image>
</Grid>
Adjust your RowDefinition(30) for the image!
Sorry if my code is not neat, as I'm on mobile.
I ended up creating a "fancy" floating button on the bottom right of the page by:
Creating a one-row Grid
Putting both the CollectionView and Image in the one row
Defining the Image after the CollectionView so that the Image sits on top of the CollectionView
I also got rid of the ScrollView per Jason's suggestion.
<ContentPage.Content>
<Grid
<CollectionView ItemsSource="{Binding MyCollection}">
<CollectionView.ItemTemplate>
<DataTemplate>
[Layout for displaying items in MyCollection...]
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Image Source="add.png" HeightRequest="40" HorizontalOptions="End"
VerticalOptions="End" Margin="0,0,50,20">
<ImageGestureRecongnizers>
<TapGestureRecognizer... Code to add new item to MyCollection...]/>
</ImageGestureRecognizers>
</Image>
</Grid>
</ContentPage.Content>
If you want to allow the viewing of the scrollable list and add items to the list by tapping an image, you can just wrap them with a Grid.
Here's the code snippet below for your reference:
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="MauiAppTest01.MainPage">
<Grid>
<CollectionView ItemsSource="{Binding MyCollection}">
<CollectionView.ItemTemplate>
<DataTemplate>
<VerticalStackLayout >
<Label Text="{Binding Name}" FontSize="Large" />
</VerticalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Image Source="dotnet_bot.png" HeightRequest="100" WidthRequest="100" HorizontalOptions="End" VerticalOptions="End" Margin="0,0,50,20">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</Image.GestureRecognizers>
</Image>
</Grid>
</ContentPage>
Code-behind:
public partial class MainPage : ContentPage
{
public ObservableCollection<MyModel> MyCollection { get; set; }
public MainPage()
    {
            InitializeComponent();
MyCollection = new ObservableCollection<MyModel>
{
new MyModel{ Name="1"},
new MyModel{ Name="2"},
};
BindingContext = this;
}
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++) {
MyCollection.Add(new MyModel { Name = i+"" });
}
}
}
Model:
public class MyModel
{
public string Name { get; set; }
}

In a ListView how to send the clicked object back to the command in the view model - Xamarin Forms

Given the following ListView, I'd like to have a command that would send the clicked object, in this case the Address, back to a command in the view model - SelectNewAddress or DeleteAddress.
<StackLayout VerticalOptions="FillAndExpand" Padding="10,15,10,15">
<Label Text="Addresses" FontSize="22" HorizontalTextAlignment="Center" FontAttributes="Bold" Padding="0,0,0,7" TextColor="#404040" />
<StackLayout VerticalOptions="FillAndExpand">
<flv:FlowListView FlowColumnCount="1"
HeightRequest="200"
SeparatorVisibility="None"
HasUnevenRows="True"
FlowItemsSource="{Binding AllAddresses}">
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate x:DataType="popups:AddressItem">
<Grid ColumnDefinitions="*,35" Padding="0,0,0,15" x:Name="Item">
<Grid Grid.Column="0">
<Grid.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding SelectNewAddress}" />
</Grid.GestureRecognizers>
<Label Text="{Binding MainAddress}"
LineBreakMode="TailTruncation"
HorizontalTextAlignment="Start"
VerticalTextAlignment="Center"
FontSize="18"
TextColor="{StaticResource CommonBlack}"/>
</Grid>
<Grid Grid.Column="1" IsVisible="{Binding IsSelected}" >
<Grid.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding SelectNewAddress}"/>
</Grid.GestureRecognizers>
<StackLayout Padding="10,0,0,0">
<flex:FlexButton Icon="check.png"
WidthRequest="25"
HeightRequest="25"
CornerRadius="18"
BackgroundColor="{StaticResource Primary}"
ForegroundColor="{StaticResource CommonWhite}"
HighlightBackgroundColor="{StaticResource PrimaryDark}"
HighlightForegroundColor="{StaticResource CommonWhite}"/>
</StackLayout>
</Grid>
<Grid Grid.Column="1" IsVisible="{Binding IsSelected, Converter={StaticResource invertBoolConverter}}">
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding DeleteAddress} />
</Grid.GestureRecognizers>
<StackLayout Padding="10,0,0,0">
<flex:FlexButton Icon="deleteCard.png"
WidthRequest="25"
HeightRequest="25"
CornerRadius="18"
BackgroundColor="{StaticResource WooopDarkGray}"
ForegroundColor="{StaticResource CommonWhite}"
HighlightBackgroundColor="{StaticResource PrimaryDark}"
HighlightForegroundColor="{StaticResource CommonWhite}"/>
</StackLayout>
</Grid>
</Grid>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
</StackLayout>
The commands in the view model are the following:
...
public ICommand SelectNewAddress { get; set; }
public ICommand DeleteAddress { get; set; }
...
public AddressSelectionViewModel()
{
DeleteAddress = new Command(DeleteAddressCommand);
SelectNewAddress = new Command(SelectNewAddressCommand);
}
...
private void SelectNewAddressCommand(object obj)
{
try
{
var item = (AddressItem)obj;
AddressHelper.UpdateAddress(item.DeliveryAddressLocation);
UpdateAddresses();
}
catch (Exception ex)
{
// TODO
}
}
private void DeleteAddressCommand(object obj)
{
try
{
var item = (AddressItem)obj;
AddressHelper.RemoveAddress(item.DeliveryAddressLocation);
UpdateAddresses();
}
catch (Exception ex)
{
// TODO
}
}
I want the object obj passed to SelectNewAddressCommand and DeleteAddressCommand to be the address clicked on the ListView
First make sure you have included your view model as DataType and view as Class inside the ContentPage:
xmlns:pages="clr-namespace:your.namespace.ViewModels"
x:DataType="pages:AddressSelectionViewModel"
x:Class="your.namespace.Views.AddressSelectionPage"
<ContentPage xmlns="..."
xmlns:x="..."
xmlns:flv="..."
xmlns:popups="..."
xmlns:flex="..."
xmlns:views="..."
xmlns:xct="..."
xmlns:pages="clr-namespace:your.namespace.ViewModels"
x:DataType="pages:AddressSelectionViewModel"
x:Class="your.namespace.Views.AddressSelectionPage"
Shell.FlyoutItemIsVisible="..."
Shell.NavBarIsVisible="..."
Shell.TabBarIsVisible="...">
Inside the top Grid element add property x:Name="Item" ("Item" is only used as an example, you can name it anything):
<flv:FlowListView FlowColumnCount="1"
HeightRequest="200"
SeparatorVisibility="None"
HasUnevenRows="True"
FlowItemsSource="{Binding AllAddresses}">
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate x:DataType="popups:AddressItem">
<Grid ColumnDefinitions="*,35" Padding="0,0,0,15" x:Name="Item"> <!-- Here -->
Then we change the Command and CommandParameter of the TapGestureRecognizer to the following:
<TapGestureRecognizer
Command="{Binding Path=SelectNewAddress, Source={RelativeSource AncestorType={x:Type pages:AddressSelectionViewModel}}}"
CommandParameter="{Binding Source={x:Reference Item}, Path=BindingContext}" />
<TapGestureRecognizer
Command="{Binding Path=DeleteAddress, Source={RelativeSource AncestorType={x:Type pages:AddressSelectionViewModel}}}"
CommandParameter="{Binding Source={x:Reference Item}, Path=BindingContext}" />
In the Command we specify the function as Path, then we clarify that the source of this function is inside the view model through AncestoryType. When inside a list view we cannot reference properties outside the object being iterated. Hence, we need to specify the desired source.
So now we are referencing the actual function. But we aren't sending the object obj as a parameter yet.
In the CommandParameter we have to pass the currently bound object with Path and Source. Note that in Source we are referencing has the name Item we defined as the x:Name of the Grid earlier.
Make sure the page has the viewmodel as its BindingContext. (If you are doing mvvm, you've already done this.)
Give <flv:FlowListView a name:
<flv:FlowListView x:Name="theListView" ... >
The item needs to refer to the command in the page's viewmodel. BindingContext propagates down through the hierarchy, so this is easily done relative to the listview name:
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
...
<TapGestureRecognizer
Command="{Binding BindingContext.SelectNewAddress, Source={x:Reference theListView}}" ...
The item's BindingContext is the item model, so that is easily passed as a parameter:
<TapGestureRecognizer
Command=... CommandParameter="{Binding .}" />
NOTE: Differences between this and Wizard's answer:
{Binding .} is all that is needed to refer to the item itself.
Instead of using RelativeSource, which requires specifying a Type, my personal preference is to name a view, then refer to that name. I find this easier to read and to remember how to do.
I left out all details that are not relevant to the question. The above steps are sufficient. (x:DataType commands are good for performance, so I am in no way suggesting not to do them. But that is a separate topic, IMHO.)

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 - My ContentPresenter won't show its Content

I'm still getting used to Xamarin Forms, so I have the following control called PopupFrame:
PopupFrame.cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PopupFrame : ContentView
{
public static readonly BindableProperty PopupContentProperty =
BindableProperty.Create(nameof(PopupContent), typeof(View), typeof(PopupFrame));
public View PopupContent
{
get { return (View)GetValue(PopupContentProperty); }
set { SetValue(PopupContentProperty, value); }
}
public PopupFrame()
{
InitializeComponent();
}
}
PopupFrame.xaml
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TestApp.Core.Controls.PopupFrame">
<Frame>
<StackLayout>
<Label Text="--- TEST TITLE ---" />
<ContentPresenter Content="{TemplateBinding PopupContent}" />
</StackLayout>
</Frame>
</ContentView>
In my view:
<popCtl:PopupFrame HorizontalOptions="Center"
VerticalOptions="Center">
<popCtl:PopupFrame.PopupContent>
<ListView x:Name="ListUsers">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Label Text="{Binding Name}"
HorizontalOptions="CenterAndExpand"
VerticalOptions="Center" />
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</popCtl:PopupFrame.PopupContent>
</popCtl:PopupFrame>
So what's happening is that When the ContentView control shows, only the Label (with the text -- TEST TITLE -- is displayed, but not the ListView).
I've also tried replacing the ContentPreseter with a ContentView, but same result: my ListView doesn't not show. And I made sure that data does in fact exist in the ItemsSource of the ListView (set in code-behind).
Is my ContentView setup wrong??
TemplateBinding can only be used to bind from inside a control-template. In order for your binding to work - you can use ReferenceExtension to refer to parent control.
For ex, update your binding as following:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TestApp.Core.Controls.PopupFrame"
x:Name="_parent">
<Frame>
<StackLayout>
<Label Text="--- TEST TITLE ---" />
<ContentPresenter
Content="{Binding Path=PopupContent, Source={x:Reference _parent}}" />
</StackLayout>
</Frame>
</ContentView>

Binding behaviors from viewmodel in listview in xamarin.forms

I have a list view which I am using to display a form.
Here is my item source:
ObservableCollection<ContactBlockFieldViewModel> ContactBlockFIelds
Each ContactBlockFieldViewModel contains public EContactFieldTypeDTO ContactField { get; set; }
I want to bind the listview entry behavior property to specific behavior, depending on what type of contact field it is.
For example, for email type I would want my custom EmailValidationBehavior.
How can I accomplish this? I tried putting the behavior right in the viewmodel and then
<ListView ItemsSource="{Binding ContactBlockFields}" x:Name="ContactFieldsList">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding FormDisplayName}" HorizontalTextAlignment="Start"></Label>
<Entry Text="{Binding Value}" BackgroundColor="{Binding BackgroundColor}">
<Entry.Behaviors>
<Binding Path="BehaviorInViewModel"></Binding>
</Entry.Behaviors>
</Entry>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
But it didn't work, I also tried to use a converter which would convert the enum to Behavior but also without success. I checked in debug and the constructor of the behavior gets called, but the object is not being bound.