我正在开发一个来自 xamarin 的应用程序,该应用程序从服务获取数据。我正在尝试做的是使名字和姓氏字段显示在同一标签中,但它当前显示名字,然后返回一行,然后显示姓氏。这是我的 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"
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>
编辑这是我的代码隐藏:
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);
}
}
}
任何帮助都会很棒!
*更新:随着 Xamarin Forms 4.7 的发布,您现在可以使用多重绑定,而不是创建 getter 属性。使用名字和姓氏示例,您将执行以下操作:
<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>
*Xamarin之前的表格4.7在这种情况下,我要做的是在组合这两个属性的模型上放置一个额外的属性。
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;
}
现在,在 ViewModel 中,如果名字或姓氏发生更改,则需要执行以下操作来更新 FirstLastName
属性:
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
}
}
}
然后对你的财产做同样的事情LastName
。
编辑:然后,XAML 将如下所示:
<StackLayout Padding="20,0,0,0" HorizontalOptions="CenterAndExpand" >
<Label x:Name="FirstName" Text="{Binding FirstLastName}"/>
.....
</StackLayout>
Edit2:因此,由于您在显示 UI 时可能永远不会更改名字或姓氏属性,您只需将该属性添加到模型中,如我在上面的ContactInfo
代码中所示,然后更改标签,就像我在上面的编辑中显示的那样,您就可以开始了。
正如Ed Phuket所说,它正在工作,但是:
如果您希望它使用OnPropertyChanged
事件更新到跨度,则需要添加Mode=OneWay
,因为它默认具有OneTime
绑定模式
虽然 Xamarin Forms 的团队仍在研究使用 Span 元素绑定,但您只需更改标签的格式即可使其正常工作:
<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>