Reputation: 1397
I'm working on an app in xamarin froms that gets data from a service. What I'm trying to do is make the first name and last name fields display in the same label however it currently displays first name then it returns a line and then shows the last name. This is my XAML code:
<?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="ReadyMo.ContactInfo">
<ListView ItemsSource="{Binding .}" HasUnevenRows="true">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame Padding="0,0,0,8" BackgroundColor="#d2d5d7">
<Frame.Content>
<Frame Padding="25,25,25,25" OutlineColor="Gray" BackgroundColor="White">
<Frame.Content>
<StackLayout Padding="20,0,0,0" HorizontalOptions="CenterAndExpand" >
<Label x:Name="FirstName" Text="{Binding First_Name}">
</Label>
<Label x:Name ="LastName" Text="{Binding Last_Name}">
</Label>
<Label x:Name="County" Text="{Binding name}">
</Label>
<Label x:Name ="Adress" Text="{Binding Address1}">
</Label>
<Label x:Name ="City" Text="{Binding Address2}">
</Label>
<Label x:Name="Number" Text="{Binding BusinessPhone}" >
</Label>
</StackLayout>
</Frame.Content>
</Frame>
</Frame.Content>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
EDIT Here's My codebehind:
using Newtonsoft.Json;
using ReadyMo.Data;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Net.Http;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace ReadyMo
{
public partial class ContactInfo : ContentPage
{
private County item;
public static async Task<string> GetContactString(string contactid)
{
HttpClient client = new HttpClient();
var url = $"URL";
var response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var responsetext = await response.Content.ReadAsStringAsync();
return responsetext;
}
throw new Exception(response.ReasonPhrase);
}
public ContactInfo()
{
InitializeComponent();
ContactInfoList = new ObservableCollection<ContactInfoModel>();
}
ObservableCollection<ContactInfoModel> ContactInfoList;
public ContactInfo(County item) : this()
{
this.item = item;
this.BindingContext = ContactInfoList;
}
protected override async void OnAppearing()
{
if (item == null)
return;
var contact = await GetContactString(item.id);
var models = JsonConvert.DeserializeObject<List<ContactInfoModel>>(contact);
foreach (var model in models)
ContactInfoList.Add(model);
}
}
}
any help would be amazing!
Upvotes: 17
Views: 29541
Reputation: 11105
*Update: With the release of Xamarin Forms 4.7, you can now use Multi-Bindings instead of creating a getter property. Using the first and last name example, you would do something like this:
<StackLayout Padding="20,0,0,0" HorizontalOptions="CenterAndExpand" >
<Label x:Name="FirstName">
<Label.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Path="FirstName" />
<Binding Path="LastName" />
</MultiBinding>
</Label.Text>
</Label>
.........
</StackLayout>
*Pre-Xamarin Forms 4.7 What I do in this situation is to put an extra property on the model that combines the two properties.
public class ContactInfo {
public string FirstName { get; set; }
public string LastName { get; set; }
public string FirstLastName { get { return FirstName + " " + LastName; }}
//Or use C# 6 goodness
//public string FirstLastName => FirstName + " " + LastName;
}
Now in your ViewModel, if first or last name changes, you would need to do something like this to update the FirstLastName
property:
private string _firstLastName;
public string FirstLastName {
get { return _firstLastName; }
set {
if(_firstLastName != value) {
_firstLastName = value;
SetPropertyChanged();
}
}
}
private string _firstName;
public string FirstName {
get { return _firstName; }
set {
if(_firstName != value) {
_firstName = value;
SetPropertyChanged();
SetPropertyChanged("FirstLastName"); //Also send alert that FirstLastName changed
}
}
}
Then do the same for you LastName
property.
Edit: Your XAML would then look like:
<StackLayout Padding="20,0,0,0" HorizontalOptions="CenterAndExpand" >
<Label x:Name="FirstName" Text="{Binding FirstLastName}"/>
.....
</StackLayout>
Edit2: So since you are probably not ever changing the First or Last Name property while showing the UI, you just need to add the property to your model, like I show in the ContactInfo
code above, and then change your label, like I show in the edit above and you will be good to go.
Upvotes: 28
Reputation: 11
As Ed Phuket said it is working but :
You need to add Mode=OneWay
if you want it to update with OnPropertyChanged
event to the span because it has OneTime
Binding mode as default
Upvotes: 1
Reputation: 27
While the team at Xamarin Forms are still figuring out Binding with the Span element, you can just change the formatting of the Labels to get this working:
<StackLayout Orientation="Horizontal" Padding="0" Margin="0" Spacing="0">
<Label Text="{Binding First_Name}" Margin="0" />
<Label Text=" " Margin="0" />
<Label Text="{Binding Last_Name}" Margin="0" />
</StackLayout>
Upvotes: -3