Xamarin forms understanding ObservableCollection binding context - xamarin

I'm having some issue getting my ObservableCollection to bind to alexrainman CarouselView.
After reading some basic articles I created my view model:
public class PostObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
string postOwner = string.Empty;
string id = string.Empty;
string profileimage = string.Empty;
string post = string.Empty;
List<string> postimages = null;
public string PostOwner
{
set
{
if (postOwner != value)
{
postOwner = value;
OnPropertyChanged("PostOwner");
}
}
get
{
return postOwner;
}
}
public string Id {
set
{
if (id != value)
{
id = value;
OnPropertyChanged("Id");
}
}
get
{
return id;
}
}
public string Post
{
set
{
if (post != value)
{
post = value;
OnPropertyChanged("Post");
}
}
get
{
return post;
}
}
public string ProfileImage
{
set
{
if (profileimage != value)
{
profileimage = value;
OnPropertyChanged("ProfileImage") ;
}
}
get
{
return profileimage;
}
}
public List<string> PostImages
{
set
{
if (postimages != value)
{
postimages = value;
OnPropertyChanged("PostImages");
}
}
get
{
return postimages;
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
I retrieve my data via a REST call to my server:
public static bool GetMyPostData(ref ObservableCollection<PostObject> myPosts, string groupid, string apikey)
{
try
{
string newURL = URL + "GetPosts";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
MultipartFormDataContent formdata = new MultipartFormDataContent
{
{ new StringContent(apikey), "apikey" },
{ new StringContent(groupid), "groupid" }
};
HttpResponseMessage response = client.PostAsync(newURL, formdata).Result; // Blocking call! Program will wait here until a response is received or a timeout occurs.
if (response.IsSuccessStatusCode)
{
try
{
myPosts = response.Content.ReadAsAsync<ObservableCollection<PostObject>>().Result;
}
catch (Exception e)
{
Debug.WriteLine(e);
return false;
}
}
}
return true;
}
catch (Exception ex)
{
Debug.WriteLine(ex);
return false;
}
}
Which works I get my data correctly, now I set up my Binding context like so:
ObservableCollection<PostObject> GroupPosts = new ObservableCollection<PostObject>();
public Posts (GroupInfo ginfo)
{
InitializeComponent ();
GroupTitle.Text = ginfo.Title;
CurrentGroupInfo = ginfo;
GetDataPosts();
BindingContext = GroupPosts;
}
public void GetDataPosts()
{
try
{
GroupPosts.Clear();
if (RestController.GetMyPostData(ref GroupPosts, CurrentGroupInfo.Id.ToString(), apikey))
{
Debug.WriteLine("Data downloaded");
}
}
catch(Exception e)
{
Debug.WriteLine(e.Message);
}
And finally I have my XAML set up like this:
<?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"
xmlns:cv="clr-namespace:CarouselView.FormsPlugin.Abstractions;assembly=CarouselView.FormsPlugin.Abstractions"
NavigationPage.HasNavigationBar="True"
NavigationPage.HasBackButton="False"
NavigationPage.BackButtonTitle="Back"
x:Class="forms.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>
<cv:CarouselViewControl x:Name="carousel"
ItemsSource="{Binding PostImages}"
ShowArrows="true"
ShowIndicators="true"
Orientation="Horizontal">
</cv:CarouselViewControl>
</ContentPage.Content>
</ContentPage>
However I get an error
Unhandled Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
So I'm not sure what I'm missing or I need to read up on this a little more? any help would be great.

You want to do a few changes here:
Change the field definition to a property, you won't be able to bind to the field:
public ObservableCollection<PostObject> GroupPosts { get; } = new ObservableCollection<PostObject>();
If you updating the reference then you have to raise property changed event, so your property definition should look like that:
private ObservableCollection<PostObject> _groupPosts = new ObservableCollection<PostObject>();
public ObservableCollection<PostObject> GroupPosts
{
get { return _groupPosts; }
set
{
_groupPosts = value;
RaisePropertyChanged(.....); // here you should notify your binding that value has changed
}
}
Because you are trying to pass this list by reference (ref parameter), you won't be able to compile it with a property so it's better just to return value from your data provider and then apply it:
GroupPosts.Clear();
var newData = RestController.GetMyPostData(CurrentGroupInfo.Id.ToString(), apikey);
GroupPosts = newData;
it's a bad practice to pass the observable collection to an underlying data provider because it will limit it to operate on UI thread only (otherwise after updating the collection on non-ui thread you can crash the app). But this is a top for another post :)

Related

Highlight URL using label span - xamarin.forms

I am creating a chat application in xamarin.forms.What I am trying to achieve is whenever user typed message contains a URL, that should be highlighted and provide click to it.For this feature I found Span in Label text.When user click on send button of chat , I will check for URL and make it as another span.I got this idea from Lucas Zhang - MSFT form this question here.
The problem is I am trying to do the spanning in view model and the individual chat bubble is in another view cell which will call as ItemTemplate in my chat listview. Anyway the spanning is not working as I intended ie; it doesn't highlight .
My view Model.
public Queue<Message> DelayedMessages { get; set; } = new Queue<Message>();
public ObservableCollection<Message> Messages { get; set; } = new ObservableCollection<Message>();
public string TextToSend { get; set; }
public ChatPageViewModel()
{
OnSendCommand = new Command(() =>
{
if (!string.IsNullOrEmpty(TextToSend))
{
var urlStr = TextToSend;
int startIndex = 0, endIndex = 0;
if (urlStr.Contains("www."))
{
startIndex = urlStr.IndexOf("www.");
}
if (urlStr.Contains(".com"))
{
endIndex = urlStr.IndexOf(".com") + 3;
}
if (startIndex != 0 || endIndex != 0)
{
var formattedString = new FormattedString();
Span span1 = new Span() { Text = urlStr.Substring(0, startIndex), TextColor = Color.Black };
formattedString.Spans.Add(span1);
Span span2 = new Span() { Text = urlStr.Substring(startIndex, endIndex - startIndex + 1), TextColor = Color.LightBlue };
span2.GestureRecognizers.Add(new TapGestureRecognizer()
{
NumberOfTapsRequired = 1,
Command = new Command(() => {
})
});
formattedString.Spans.Add(span2);
Span span3 = new Span() { Text = urlStr.Substring(endIndex, urlStr.Length - 1 - endIndex), TextColor = Color.Black };
formattedString.Spans.Add(span3);
var message = new Message
{
Text = formattedString.ToString(),
IsIncoming = false,
MessageDateTime = DateTime.Now
};
Messages.Add(message);
TextToSend = string.Empty;
}
else
{
var message = new Message
{
Text = urlStr.ToString(),
IsIncoming = false,
MessageDateTime = DateTime.Now
};
Messages.Add(message);
TextToSend = string.Empty;
}
}
});
}
Single chat Bubble XAML
<Label x:Name="OutgoingMessage" TextColor="White" FormattedText="{Binding Text}" HorizontalOptions="End" >
</Label>
My Chat page XAML
<Grid RowSpacing="0" Margin="0,20,0,0"
ColumnSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="1" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListView Grid.Row="0"
ItemTemplate="{StaticResource MessageTemplateSelector}"
ItemsSource="{Binding Messages,Mode=OneWay}"
Margin="0"
SelectionMode="None"
FlowDirection="RightToLeft"
HasUnevenRows="True" x:Name="ChatList"
VerticalOptions="FillAndExpand"
SeparatorColor="Transparent"
>
</ListView>
<BoxView HorizontalOptions="FillAndExpand"
HeightRequest="1"
BackgroundColor="#F2F3F5"
Grid.Row="1"/>
<partials:ChatInputBarView Grid.Row="2"
Margin="0,0,0,0"
x:Name="chatInput"/>
</Grid>
ChatPage.xaml.cs
public partial class ChatPage : ContentPage
{
ChatPageViewModel vm;
public ChatPage()
{
InitializeComponent();
this.BindingContext = vm= new ChatPageViewModel();
}
}
Messages class
public class Message : ObservableObject
{
string text;
public string Text
{
get { return text; }
set { SetProperty(ref text, value); }
}
DateTime messageDateTime;
public DateTime MessageDateTime
{
get { return messageDateTime; }
set { SetProperty(ref messageDateTime, value); }
}
public string MessageTimeDisplay => MessageDateTime.Humanize();
bool isIncoming;
public bool IsIncoming
{
get { return isIncoming; }
set { SetProperty(ref isIncoming, value); }
}
}
Any Help is appreciated.
EDIT:
This question was actually continuation of question. Previously I used AwesomeHyperLinkLabel fromlink. The problem was I cant manage the click event of that label.Thats why I moved with label span.Thanks to Leo Zhu - MSFT For the render changes.
For Android:
[assembly: ExportRenderer(typeof(AwesomeHyperLinkLabel), typeof(AwesomeHyperLinkLabelRenderer))]
namespace App18.Droid
{
public class AwesomeHyperLinkLabelRenderer : LabelRenderer
{
public AwesomeHyperLinkLabelRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
var view = (AwesomeHyperLinkLabel)Element;
if (view == null) return;
TextView textView = new TextView(Forms.Context);
textView.LayoutParameters = new LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent);
textView.SetTextColor(view.TextColor.ToAndroid());
// Setting the auto link mask to capture all types of link-able data
textView.AutoLinkMask = MatchOptions.All;
// Make sure to set text after setting the mask
textView.Text = view.Text;
AddHyperlinksManually(textView);
//textView.SetTextSize(ComplexUnitType.Dip, (float)view.FontSize);
// overriding Xamarin Forms Label and replace with our native control
SetNativeControl(textView);
}
public static void AddHyperlinksManually(TextView _tv)
{
SpannableStringBuilder currentSpan = new SpannableStringBuilder(_tv.Text);
Linkify.AddLinks(currentSpan, MatchOptions.WebUrls);
var objects = currentSpan.GetSpans(0, currentSpan.Length(), Java.Lang.Class.FromType(typeof(URLSpan)));
var urlSpans = new URLSpan[objects.Length];
for (var i = 0; i < urlSpans.Length; i++)
{
urlSpans[i] = objects[i] as URLSpan;
}
foreach (URLSpan _url in urlSpans)
{
int iStart = currentSpan.GetSpanStart(_url);
int iEnd = currentSpan.GetSpanEnd(_url);
currentSpan.RemoveSpan(_url);
currentSpan.SetSpan(new CustomURLSpan(_url.URL), iStart, iEnd, SpanTypes.InclusiveInclusive);
_tv.SetText(currentSpan, TextView.BufferType.Normal);
_tv.MovementMethod = LinkMovementMethod.Instance;
}
}
public class CustomURLSpan : ClickableSpan
{
string mTargetURL;
public CustomURLSpan(string _url) {
mTargetURL =_url;
}
public override void OnClick(Android.Views.View widget)
{
//here you could handle the click event,and you could use MessagingCenter to send mTargetURL to your Page.
Console.WriteLine("Click");
}
}
}
The mistake was with my model.Changed string to FormattedString and also changed in the viewmodel
public class Message : ObservableObject
{
FormattedString text;
public FormattedString Text
{
get { return text; }
set { SetProperty(ref text, value); }
}
DateTime messageDateTime;
public DateTime MessageDateTime
{
get { return messageDateTime; }
set { SetProperty(ref messageDateTime, value); }
}
public string MessageTimeDisplay => MessageDateTime.Humanize();
bool isIncoming;
public bool IsIncoming
{
get { return isIncoming; }
set { SetProperty(ref isIncoming, value); }
}
}

How to set/get the properties Grial Repeater?

refer to http://docs.grialkit.com/repeater.html, it got a property
call 'SelectedItem', i want to know the code in detail how to set or get it ?
Please help, thanks!
This is how you will get the SelectedItem, I am assuming you are following the MVVM approach.
XAML:-
<grial:Repeater Spacing="8"
Padding="10"
ScrollPadding="10"
ItemsSource="{Binding Items}"
SelectedItem= "{Binding SelectedItemObject}">
<grial:Repeater.ItemTemplate>
<!--DEFAULT ITEM TEMPLATE-->
</grial:Repeater.ItemTemplate>
</grial:Repeater>
ViewModel:
private ModelClass _selectedItemObject;
public ModelClass SelectedItemObject
{
get { return _selectedItemObject; }
set
{
_selectedItemObject = value;
OnPropertyChanged("SelectedItemObject");
OnItemSelected(SelectedItemObject);
}
}
private List<ModelClass> _items;
public List<ModelClass> Items
{
get{ return _items;}
set
{
_items = value;
OnPropertyChanged("Items");
}
}
private void OnItemSelected(ModelClass selectedItem)
{
if (selectedItem == null)
return;
// Perform your logic her on selection
}

How to display the registered data from database in text field in Xamarin Forms to update

I would like to Update/Editthe player details in my Xamarin Forms app. Once the player is logged in to the app, on click on the profile image should navigate to Player Details (Register.xaml) screen with player details populated from database. How to get the data displayed in text fields?
// The Register.xaml:
<ContentPage.Content>
<StackLayout Spacing="20" Padding="20">
<Label Text="Player Details" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" FontSize="25"></Label>
<Entry x:Name="fullNameEntry" Placeholder="Full Name" Text="{Binding FullName}"></Entry>
<Entry x:Name="mobileEntry" Placeholder="Mobile" Text="{Binding Mobile}"></Entry>
<Entry x:Name="soccerpostionEntry" Placeholder="Soccer Position" Text="{Binding SoccerPosition}"></Entry>
<Button Text="Register" Clicked="RegisterSave_OnClicked" TextColor="White" BackgroundColor="ForestGreen"></Button>
</StackLayout>
</ContentPage.Content>
Below OnProfilePicClicked will grab the logged in user from database
private async void OnProfilePicClicked(object sender, EventArgs e)
{
//Navigate to Register screen with player data loaded:
var emailText = emailEntry.Text;
await Navigation.PushAsync(new Register(){});
List<PlayerDetails> details = (from x in conn.Table<PlayerDetails>() where x.Email == emailText select x).ToList();
if (details!= null)
{
// found the record
PlayerDetails playerDetails = new PlayerDetails();
playerDetails.FullName = details[0].FullName;
playerDetails.Mobile = details[0].Mobile;
playerDetails.SoccerPosition = details[0].SoccerPosition;
}
}
PlayerDetails model class:
string fullname;
string mobile;
string soccerposition;
public PlayerDetails()
{
}
public string FullName
{
set
{
if (fullname != value)
{
fullname = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("FullName"));
}
}
}
get
{
return fullname;
}
}
public string Mobile
{
set
{
if (mobile != value)
{
mobile = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Mobile"));
}
}
}
get
{
return mobile;
}
}
public string SoccerPosition
{
set
{
if (soccerposition != value)
{
soccerposition = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("SoccerPosition"));
}
}
}
get
{
return soccerposition;
}
}
Solution:
You should pass the model when you pushing to Register page.
In your Register page, add a PlayerDetails parameter in the construction function and set BindingContext to the model:
public partial class Register : ContentPage
{
PlayerDetails myDetails;
public Register(PlayerDetails playD)
{
InitializeComponent ();
myDetails = playD;
BindingContext = myDetails;
}
}
And when you push, pass the model:
private async void OnProfilePicClicked(object sender, EventArgs e)
{
//Navigate to Register screen with player data loaded:
var emailText = emailEntry.Text;
List<PlayerDetails> details = (from x in conn.Table<PlayerDetails>() where x.Email == emailText select x).ToList();
if (details != null)
{
// found the record
PlayerDetails playerDetails = new PlayerDetails();
playerDetails.FullName = details[0].FullName;
playerDetails.Mobile = details[0].Mobile;
playerDetails.SoccerPosition = details[0].SoccerPosition;
await Navigation.PushAsync(new Register(playerDetails) { });
}
else {
Console.WriteLine("Can't find the playerDetails");
}
}

Use search command of search bar on list view with mvvm pattern

I'm a beginner on xamarin mvvm patter. Currently I'm trying to create a search bar that searches the word from a list of names. I tried to write some codes on comman function on my view model and bind it on the SearchCommand of search bar on view. But it didn't work. Here's my code
namespace HelloWorld.ViewModel
{
public class CustViewModel : INotifyPropertyChanged
{
private custmodel _custmodel;
public custmodel custmodel
{
get { return _custmodel; }
set
{
_custmodel = value;
NotifyPropertyChanged();
}
}
private string _message;
public string message
{
get { return _message; }
set
{
_message = value;
NotifyPropertyChanged();
}
}
private ObservableCollection<string> _list;
public ObservableCollection<string> Items
{
get
{
return _list;
}
set
{
_list = value;
NotifyPropertyChanged();
}
}
public Command SaveCommand
{
get
{
return new Command(() =>
{
message = "Your task : " + custmodel.name + ", " + custmodel.surname + " was successfully saved!";
});
}
}
private string _bar;
public string Bar
{
get { return _bar; }
set { _bar = value;
}
}
public Command SearchCommand
{
get
{
return new Command(() =>
{
string keyword = _bar;
IEnumerable<String> searchresult = _list.Where(name => name.Contains(keyword));
_list = new ObservableCollection<string>(searchresult);
NotifyPropertyChanged();
}
);
}
}
public CustViewModel()
{
custmodel = new custmodel
{
name = "Aasish",
surname = "Gurung",
email = "iamaaceez#yahoo.com"
};
_list = new ObservableCollection<string>();
_list.Add("Saurab");
_list.Add("Basanta");
_list.Add("Abhishek");
_list.Add("Surace");
_list.Add("Amir");
}
public event PropertyChangedEventHandler PropertyChanged;
//public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Here is my xaml file
<?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="HelloWorld.Styling"
BackgroundColor="AntiqueWhite" Title="Hello"
xmlns:converters="clr-namespace:HelloWorld.Converters; assembly=HelloWorld">
<StackLayout>
<SearchBar x:Name="MainSearchBar" Text="{Binding Bar}"
SearchCommand="{Binding SearchCommand}"/>
<ListView ItemsSource="{Binding Items}"/>
</StackLayout>
First, make sure you are setting your ContentPage's BindingContext to your CustViewModel.
Also, you should stop assigning and adding things to _list and instead assign and add things to your public Items property. Items is the one that will trigger the NotifyPropertyChanged() method when it has been assigned to.
So change your SearchCommand to this:
return new Command(() => {
string keyword = _bar;
IEnumerable<String> searchresult = _list.Where(name => name.Contains(keyword));
Items = new ObservableCollection<string>(searchresult);
//NotifyPropertyChanged(); //There is no reason to trigger NotifyPropertyChanged on this command each time the getter is run, I would image that this could cause an infinite loop
});

How do I solve Xamarin.Forms.Xaml.XamlParseException

I am new to Xamarin Forms and C# too. Kindly help me to get rid of the above issue.
I am getting
Xamarin.Forms.Xaml.XamlParseException
while I am trying to add the string format of my selected image source to CandidateDetails.cs.
The pages are as follow:
CandidateDetails.cs
public event PropertyChangedEventHandler PropertyChanged;
private string imageBase64;
public string ImageBase64
{
get { return imageBase64; }
set
{
imageBase64 = value;
OnPropertyChanged("ImageBase64");
CandImage = Xamarin.Forms.ImageSource.FromStream(
() => new MemoryStream(Convert.FromBase64String(imageBase64)));
}
}
private Xamarin.Forms.ImageSource _candImage;
public Xamarin.Forms.ImageSource CandImage
{
get { return _candImage; }
set
{
_candImage = value;
OnPropertyChanged("CandImage");
}
}
public string _candName;
public string CandName
{
get { return _candName; }
set
{
if (_candName == value)
return;
_candName = value;
OnPropertyChanged("CandName");
}
}
public string _candInst;
public string CandInst
{
get { return _candInst; }
set
{
if (_candInst == value)
return;
_candInst = value;
OnPropertyChanged("CandInst");
}
}
public string _candEmailId;
public string CandEmailId
{
get { return _candEmailId; }
set
{
if (_candEmailId == value)
return;
_candEmailId = value;
OnPropertyChanged("CandEmailId");
}
}
public string _candMob;
public string CandMob
{
get { return _candMob; }
set
{
if (_candMob == value)
return;
_candMob = value;
OnPropertyChanged("CandMob");
}
}
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
CandidateDetailsModalPage.xaml.cs
public partial class CandidateDetailsModalPage : ContentPage
{
Stream input;
string imageAsString;
public static ObservableCollection<CandidateDetails> _candidate = new ObservableCollection<CandidateDetails>();
async void OnDoneClicked(object sender, System.EventArgs e)
{
_candidate.Add(new CandidateDetails
{
CandName = (string)candNameEntry.Text,
CandEmailId = (string)candEmailId.Text,
CandMob = (string)candMobNumber.Text,
ImageBase64 = imageAsString
});
await Navigation.PopModalAsync();
}
public CandidateDetailsModalPage()
{
InitializeComponent();
pickPhoto.Clicked += async (sender, args) =>
{
if (!CrossMedia.Current.IsPickPhotoSupported)
{
await DisplayAlert("Photos Not Supported", ":( Permission not granted to photos.", "OK");
return;
}
var file = await CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Medium
});
if (file == null)
return;
input = file.GetStream();
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
imageAsString = Convert.ToBase64String(ms.ToArray());
}
//image.Source = ImageSource.FromStream(() => new MemoryStream(Convert.FromBase64String(imageAsString)));
image.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
};
}
}
CandidateDetailsModalPage.xaml
<StackLayout Orientation="Vertical" BackgroundColor="#3B4371" Padding="0">
<Button Text="Done" Clicked="OnDoneClicked" />
<ic:CircleImage x:Name="image"/>
<Button x:Name="pickPhoto" Text="Pick Photo"/>
<StackLayout VerticalOptions="FillAndExpand">
<Entry x:Name="candNameEntry" Placeholder="Candidate Name" />
<Entry x:Name="candInst" Placeholder="Candidate Institution / Party"/>
<Entry x:Name="candEmailId" Placeholder="Candidate Email Id" />
<Entry x:Name="candMobNumber" Placeholder="Candidate Mobile Number"/>
</StackLayout>
</StackLayout>
The following is the backend of the xaml page where I am displaying the data CandidateDisplayPage.xaml.cs
candidateListView.ItemsSource = CandidateDetailsModalPage._candidate;
CandidateDisplayPage
<ListView x:Name="candidateListView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Image x:Name="candImage" ImageSource="{Binding Path=CandImage}"/>
<Label Text="{Binding CandName}" x:Name="candName"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You say in a comment (that should have been part of the original report):
This is the error that's causing the exception Cannot assign property "ImageSource": Property does not exists, or is not assignable, or mismatching type between value and property
Indeed, Image doesn't have an ImageSource property, but instead a Source property of type ImageSource.
public ImageSource Source { get; set; }
So your Xaml should look like
Image x:Name="candImage" Source="{Binding Path=CandImage}"/>

Resources