how to have 2 data binding fields in one Xamarin forms label?

24,168

Solution 1

*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.

Solution 2

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

Share:
24,168
Phoneswapshop
Author by

Phoneswapshop

Updated on October 05, 2021

Comments

  • Phoneswapshop
    Phoneswapshop over 2 years

    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!

  • 15ee8f99-57ff-4f92-890c-b56153
    15ee8f99-57ff-4f92-890c-b56153 about 8 years
    This is probably OP's best bet.
  • Phoneswapshop
    Phoneswapshop about 8 years
    Thanks for the reply! is there a way to do it via xaml? please let me know :)
  • hvaughan3
    hvaughan3 about 8 years
    @Phoneswapshop No problem. The original answer is completely compatible with XAML as is but I added an example of what your XAML would look like after the change.
  • Phoneswapshop
    Phoneswapshop about 8 years
    I'm having implementing your code into mine i have added my code behind via a edit in the question can you please look at it and suggest how to put your snippet in there thanks in advance! :)
  • hvaughan3
    hvaughan3 about 8 years
    @Phoneswapshop Sorry about that. Was not thinking about the fact that you were doing things in a ListView see edit 2 and let me know if you are still having issues.
  • hvaughan3
    hvaughan3 about 8 years
    @Phoneswapshop Did this fix your issue?
  • hvaughan3
    hvaughan3 about 8 years
    @Phoneswapshop No problem, glad it did.